From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mikko Perttunen Subject: Re: [PATCH 2/2] drm/tegra: Do not implement runtime PM Date: Wed, 4 Dec 2019 10:37:04 +0200 Message-ID: <61acda7c-f5c8-e7f6-0e34-c25bec489cdc@kapsi.fi> References: <20191203162733.1436800-1-thierry.reding@gmail.com> <20191203162733.1436800-2-thierry.reding@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8"; Format="flowed" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20191203162733.1436800-2-thierry.reding@gmail.com> Content-Language: en-US List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Thierry Reding Cc: linux-tegra@vger.kernel.org, "Rafael J. Wysocki" , dri-devel@lists.freedesktop.org, linux-pm@vger.kernel.org List-Id: linux-tegra@vger.kernel.org SXMgdGhlcmUgYW55IHNwZWNpZmljIHJlYXNvbiBub24tZGlzcGxheSBlbmdpbmVzIGxpa2UgVklD IGNhbm5vdCAKY29udGludWUgdG8gdXNlIHJ1bnRpbWUgUE0/IEkga25vdyBiZWluZyBhYmxlIHRv IGRvICdlY2hvIG9uID4gCnBvd2VyL2NvbnRyb2wnIGZvciBWSUMgaGFzIGJlZW4gcXVpdGUgdXNl ZnVsIGZvciBkZWJ1Z2dpbmcgaW4gdGhlIHBhc3QuCgpNaWtrbwoKT24gMy4xMi4yMDE5IDE4LjI3 LCBUaGllcnJ5IFJlZGluZyB3cm90ZToKPiBGcm9tOiBUaGllcnJ5IFJlZGluZyA8dHJlZGluZ0Bu dmlkaWEuY29tPgo+IAo+IFRoZSBUZWdyYSBEUk0gZHJpdmVyIGhlYXZpbHkgcmVsaWVzIG9uIHRo ZSBpbXBsZW1lbnRhdGlvbnMgZm9yIHJ1bnRpbWUKPiBzdXNwZW5kL3Jlc3VtZSB0byBiZSBjYWxs ZWQgYXQgc3BlY2lmaWMgdGltZXMuIFVuZm9ydHVuYXRlbHksIHRoZXJlIGFyZQo+IHNvbWUgY2Fz ZXMgd2hlcmUgdGhhdCBkb2Vzbid0IHdvcmsuIE9uZSBleGFtcGxlIGlzIGlmIHRoZSB1c2VyIGRp c2FibGVzCj4gcnVudGltZSBQTSBmb3IgYSBnaXZlbiBzdWJkZXZpY2UuIEFub3RoZXIgZXhhbXBs ZSBpcyB0aGF0IHRoZSBQTSBjb3JlCj4gYWNxdWlyZXMgYSByZWZlcmVuY2UgdG8gcnVudGltZSBQ TSBkdXJpbmcgc3lzdGVtIHNsZWVwLCBlZmZlY3RpdmVseQo+IHByZXZlbnRpbmcgZGV2aWNlcyBm cm9tIGdvaW5nIGludG8gbG93IHBvd2VyIG1vZGVzLiBUaGlzIGlzIGludGVudGlvbmFsCj4gdG8g YXZvaWQgbmFzdHkgcmFjZSBjb25kaXRpb25zLCBidXQgaXQgYWxzbyBjYXVzZXMgc3lzdGVtIHNs ZWVwIHRvIG5vdAo+IGZ1bmN0aW9uIHByb3Blcmx5IG9uIGFsbCBUZWdyYSBzeXN0ZW1zLgo+IAo+ IEZpeCB0aGlzIGJ5IG5vdCBpbXBsZW1lbnRpbmcgcnVudGltZSBQTSBhdCBhbGwuIEluc3RlYWQs IGEgbWluaW1hbCwKPiByZWZlcmVuY2UtY291bnRlZCBzdXNwZW5kL3Jlc3VtZSBpbmZyYXN0cnVj dHVyZSBpcyBhZGRlZCB0byB0aGUgaG9zdDF4Cj4gYnVzLiBUaGlzIGhhcyB0aGUgYmVuZWZpdCB0 aGF0IGl0IGNhbiBiZSB1c2VkIHJlZ2FyZGxlc3Mgb2YgdGhlIHN5c3RlbQo+IHBvd2VyIHN0YXRl IChvciBhbnkgdHJhbnNpdGlvbnMgd2UgbWlnaHQgYmUgaW4pLCBvciB3aGV0aGVyIG9yIG5vdCB0 aGUKPiB1c2VyIGFsbG93cyBydW50aW1lIFBNLgo+IAo+IEF0b21pYyBtb2Rlc2V0dGluZyBndWFy YW50ZWVzIHRoYXQgdGhlc2UgZnVuY3Rpb25zIHdpbGwgZW5kIHVwIGJlaW5nCj4gY2FsbGVkIGF0 IHRoZSByaWdodCBwb2ludCBpbiB0aW1lLCBzbyB0aGUgcGl0ZmFsbHMgZm9yIHRoZSBtb3JlIGdl bmVyaWMKPiBydW50aW1lIFBNIGRvIG5vdCBhcHBseSBoZXJlLgo+IAo+IFNpZ25lZC1vZmYtYnk6 IFRoaWVycnkgUmVkaW5nIDx0cmVkaW5nQG52aWRpYS5jb20+Cj4gLS0tCj4gICBkcml2ZXJzL2dw dS9kcm0vdGVncmEvZGMuYyAgICB8IDE0MSArKysrKysrKysrKysrKy0tLS0tLS0tLS0KPiAgIGRy aXZlcnMvZ3B1L2RybS90ZWdyYS9kcGF1eC5jIHwgICAyICstCj4gICBkcml2ZXJzL2dwdS9kcm0v dGVncmEvZHJtLmggICB8ICAgMiArCj4gICBkcml2ZXJzL2dwdS9kcm0vdGVncmEvZHNpLmMgICB8 IDE3NSArKysrKysrKysrKysrKysrLS0tLS0tLS0tLS0tLS0KPiAgIGRyaXZlcnMvZ3B1L2RybS90 ZWdyYS9oZG1pLmMgIHwgMTE2ICsrKysrKysrKysrLS0tLS0tLS0tCj4gICBkcml2ZXJzL2dwdS9k cm0vdGVncmEvaHViLmMgICB8IDE5NCArKysrKysrKysrKysrKysrKysrKy0tLS0tLS0tLS0tLS0t Cj4gICBkcml2ZXJzL2dwdS9kcm0vdGVncmEvaHViLmggICB8ICAgMiArLQo+ICAgZHJpdmVycy9n cHUvZHJtL3RlZ3JhL3Nvci5jICAgfCAxNTQgKysrKysrKysrKysrKysrLS0tLS0tLS0tLS0tCj4g ICBkcml2ZXJzL2dwdS9kcm0vdGVncmEvdmljLmMgICB8IDEzMSArKysrKysrKysrKy0tLS0tLS0t LS0tLQo+ICAgZHJpdmVycy9ncHUvaG9zdDF4L2J1cy5jICAgICAgfCAgNzUgKysrKysrKysrKysr Kwo+ICAgaW5jbHVkZS9saW51eC9ob3N0MXguaCAgICAgICAgfCAgMTEgKysKPiAgIDExIGZpbGVz IGNoYW5nZWQsIDYwNCBpbnNlcnRpb25zKCspLCAzOTkgZGVsZXRpb25zKC0pCj4gCj4gZGlmZiAt LWdpdCBhL2RyaXZlcnMvZ3B1L2RybS90ZWdyYS9kYy5jIGIvZHJpdmVycy9ncHUvZHJtL3RlZ3Jh L2RjLmMKPiBpbmRleCAyOTgzZWIzM2YyYmUuLjg3MTA0NmYzZjQ2OSAxMDA2NDQKPiAtLS0gYS9k cml2ZXJzL2dwdS9kcm0vdGVncmEvZGMuYwo+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS90ZWdyYS9k Yy5jCj4gQEAgLTE3MzcsNiArMTczNyw3IEBAIHN0YXRpYyB2b2lkIHRlZ3JhX2NydGNfYXRvbWlj X2Rpc2FibGUoc3RydWN0IGRybV9jcnRjICpjcnRjLAo+ICAgewo+ICAgCXN0cnVjdCB0ZWdyYV9k YyAqZGMgPSB0b190ZWdyYV9kYyhjcnRjKTsKPiAgIAl1MzIgdmFsdWU7Cj4gKwlpbnQgZXJyOwo+ ICAgCj4gICAJaWYgKCF0ZWdyYV9kY19pZGxlKGRjKSkgewo+ICAgCQl0ZWdyYV9kY19zdG9wKGRj KTsKPiBAQCAtMTc4Myw3ICsxNzg0LDkgQEAgc3RhdGljIHZvaWQgdGVncmFfY3J0Y19hdG9taWNf ZGlzYWJsZShzdHJ1Y3QgZHJtX2NydGMgKmNydGMsCj4gICAKPiAgIAlzcGluX3VubG9ja19pcnEo JmNydGMtPmRldi0+ZXZlbnRfbG9jayk7Cj4gICAKPiAtCXBtX3J1bnRpbWVfcHV0X3N5bmMoZGMt PmRldik7Cj4gKwllcnIgPSBob3N0MXhfY2xpZW50X3N1c3BlbmQoJmRjLT5jbGllbnQpOwo+ICsJ aWYgKGVyciA8IDApCj4gKwkJZGV2X2VycihkYy0+ZGV2LCAiZmFpbGVkIHRvIHN1c3BlbmQ6ICVk XG4iLCBlcnIpOwo+ICAgfQo+ICAgCj4gICBzdGF0aWMgdm9pZCB0ZWdyYV9jcnRjX2F0b21pY19l bmFibGUoc3RydWN0IGRybV9jcnRjICpjcnRjLAo+IEBAIC0xNzkzLDggKzE3OTYsMTMgQEAgc3Rh dGljIHZvaWQgdGVncmFfY3J0Y19hdG9taWNfZW5hYmxlKHN0cnVjdCBkcm1fY3J0YyAqY3J0YywK PiAgIAlzdHJ1Y3QgdGVncmFfZGNfc3RhdGUgKnN0YXRlID0gdG9fZGNfc3RhdGUoY3J0Yy0+c3Rh dGUpOwo+ICAgCXN0cnVjdCB0ZWdyYV9kYyAqZGMgPSB0b190ZWdyYV9kYyhjcnRjKTsKPiAgIAl1 MzIgdmFsdWU7Cj4gKwlpbnQgZXJyOwo+ICAgCj4gLQlwbV9ydW50aW1lX2dldF9zeW5jKGRjLT5k ZXYpOwo+ICsJZXJyID0gaG9zdDF4X2NsaWVudF9yZXN1bWUoJmRjLT5jbGllbnQpOwo+ICsJaWYg KGVyciA8IDApIHsKPiArCQlkZXZfZXJyKGRjLT5kZXYsICJmYWlsZWQgdG8gcmVzdW1lOiAlZFxu IiwgZXJyKTsKPiArCQlyZXR1cm47Cj4gKwl9Cj4gICAKPiAgIAkvKiBpbml0aWFsaXplIGRpc3Bs YXkgY29udHJvbGxlciAqLwo+ICAgCWlmIChkYy0+c3luY3B0KSB7Cj4gQEAgLTIwMjIsNiArMjAz MCwxNSBAQCBzdGF0aWMgaW50IHRlZ3JhX2RjX2luaXQoc3RydWN0IGhvc3QxeF9jbGllbnQgKmNs aWVudCkKPiAgIAlpZiAoIXRlZ3JhX2RjX2hhc193aW5kb3dfZ3JvdXBzKGRjKSkKPiAgIAkJcmV0 dXJuIDA7Cj4gICAKPiArCS8qCj4gKwkgKiBTZXQgdGhlIGRpc3BsYXkgaHViIGFzIHRoZSBob3N0 MXggY2xpZW50IHBhcmVudCBmb3IgdGhlIGRpc3BsYXkKPiArCSAqIGNvbnRyb2xsZXIuIFRoaXMg aXMgbmVlZGVkIGZvciB0aGUgcnVudGltZSByZWZlcmVuY2UgY291bnRpbmcgdGhhdAo+ICsJICog ZW5zdXJlcyB0aGUgZGlzcGxheSBodWIgaXMgYWx3YXlzIHBvd2VyZWQgd2hlbiBhbnkgb2YgdGhl IGRpc3BsYXkKPiArCSAqIGNvbnRyb2xsZXJzIGFyZS4KPiArCSAqLwo+ICsJaWYgKGRjLT5zb2Mt Pmhhc19udmRpc3BsYXkpCj4gKwkJY2xpZW50LT5wYXJlbnQgPSAmdGVncmEtPmh1Yi0+Y2xpZW50 Owo+ICsKPiAgIAlkYy0+c3luY3B0ID0gaG9zdDF4X3N5bmNwdF9yZXF1ZXN0KGNsaWVudCwgZmxh Z3MpOwo+ICAgCWlmICghZGMtPnN5bmNwdCkKPiAgIAkJZGV2X3dhcm4oZGMtPmRldiwgImZhaWxl ZCB0byBhbGxvY2F0ZSBzeW5jcG9pbnRcbiIpOwo+IEBAIC0yMTMxLDkgKzIxNDgsNzQgQEAgc3Rh dGljIGludCB0ZWdyYV9kY19leGl0KHN0cnVjdCBob3N0MXhfY2xpZW50ICpjbGllbnQpCj4gICAJ cmV0dXJuIDA7Cj4gICB9Cj4gICAKPiArc3RhdGljIGludCB0ZWdyYV9kY19ydW50aW1lX3N1c3Bl bmQoc3RydWN0IGhvc3QxeF9jbGllbnQgKmNsaWVudCkKPiArewo+ICsJc3RydWN0IHRlZ3JhX2Rj ICpkYyA9IGhvc3QxeF9jbGllbnRfdG9fZGMoY2xpZW50KTsKPiArCXN0cnVjdCBkZXZpY2UgKmRl diA9IGNsaWVudC0+ZGV2Owo+ICsJaW50IGVycjsKPiArCj4gKwllcnIgPSByZXNldF9jb250cm9s X2Fzc2VydChkYy0+cnN0KTsKPiArCWlmIChlcnIgPCAwKSB7Cj4gKwkJZGV2X2VycihkZXYsICJm YWlsZWQgdG8gYXNzZXJ0IHJlc2V0OiAlZFxuIiwgZXJyKTsKPiArCQlyZXR1cm4gZXJyOwo+ICsJ fQo+ICsKPiArCWlmIChkYy0+c29jLT5oYXNfcG93ZXJnYXRlKQo+ICsJCXRlZ3JhX3Bvd2VyZ2F0 ZV9wb3dlcl9vZmYoZGMtPnBvd2VyZ2F0ZSk7Cj4gKwo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJl KGRjLT5jbGspOwo+ICsJcG1fcnVudGltZV9wdXRfc3luYyhkZXYpOwo+ICsKPiArCXJldHVybiAw Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHRlZ3JhX2RjX3J1bnRpbWVfcmVzdW1lKHN0cnVjdCBo b3N0MXhfY2xpZW50ICpjbGllbnQpCj4gK3sKPiArCXN0cnVjdCB0ZWdyYV9kYyAqZGMgPSBob3N0 MXhfY2xpZW50X3RvX2RjKGNsaWVudCk7Cj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSBjbGllbnQt PmRldjsKPiArCWludCBlcnI7Cj4gKwo+ICsJZXJyID0gcG1fcnVudGltZV9nZXRfc3luYyhkZXYp Owo+ICsJaWYgKGVyciA8IDApIHsKPiArCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBnZXQgcnVu dGltZSBQTTogJWRcbiIsIGVycik7Cj4gKwkJcmV0dXJuIGVycjsKPiArCX0KPiArCj4gKwlpZiAo ZGMtPnNvYy0+aGFzX3Bvd2VyZ2F0ZSkgewo+ICsJCWVyciA9IHRlZ3JhX3Bvd2VyZ2F0ZV9zZXF1 ZW5jZV9wb3dlcl91cChkYy0+cG93ZXJnYXRlLCBkYy0+Y2xrLAo+ICsJCQkJCQkJZGMtPnJzdCk7 Cj4gKwkJaWYgKGVyciA8IDApIHsKPiArCQkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gcG93ZXIg cGFydGl0aW9uOiAlZFxuIiwgZXJyKTsKPiArCQkJZ290byBwdXRfcnBtOwo+ICsJCX0KPiArCX0g ZWxzZSB7Cj4gKwkJZXJyID0gY2xrX3ByZXBhcmVfZW5hYmxlKGRjLT5jbGspOwo+ICsJCWlmIChl cnIgPCAwKSB7Cj4gKwkJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGVuYWJsZSBjbG9jazogJWRc biIsIGVycik7Cj4gKwkJCWdvdG8gcHV0X3JwbTsKPiArCQl9Cj4gKwo+ICsJCWVyciA9IHJlc2V0 X2NvbnRyb2xfZGVhc3NlcnQoZGMtPnJzdCk7Cj4gKwkJaWYgKGVyciA8IDApIHsKPiArCQkJZGV2 X2VycihkZXYsICJmYWlsZWQgdG8gZGVhc3NlcnQgcmVzZXQ6ICVkXG4iLCBlcnIpOwo+ICsJCQln b3RvIGRpc2FibGVfY2xrOwo+ICsJCX0KPiArCX0KPiArCj4gKwlyZXR1cm4gMDsKPiArCj4gK2Rp c2FibGVfY2xrOgo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKGRjLT5jbGspOwo+ICtwdXRfcnBt Ogo+ICsJcG1fcnVudGltZV9wdXRfc3luYyhkZXYpOwo+ICsJcmV0dXJuIGVycjsKPiArfQo+ICsK PiAgIHN0YXRpYyBjb25zdCBzdHJ1Y3QgaG9zdDF4X2NsaWVudF9vcHMgZGNfY2xpZW50X29wcyA9 IHsKPiAgIAkuaW5pdCA9IHRlZ3JhX2RjX2luaXQsCj4gICAJLmV4aXQgPSB0ZWdyYV9kY19leGl0 LAo+ICsJLnN1c3BlbmQgPSB0ZWdyYV9kY19ydW50aW1lX3N1c3BlbmQsCj4gKwkucmVzdW1lID0g dGVncmFfZGNfcnVudGltZV9yZXN1bWUsCj4gICB9Owo+ICAgCj4gICBzdGF0aWMgY29uc3Qgc3Ry dWN0IHRlZ3JhX2RjX3NvY19pbmZvIHRlZ3JhMjBfZGNfc29jX2luZm8gPSB7Cj4gQEAgLTI1NDUs NjUgKzI2MjcsMTAgQEAgc3RhdGljIGludCB0ZWdyYV9kY19yZW1vdmUoc3RydWN0IHBsYXRmb3Jt X2RldmljZSAqcGRldikKPiAgIAlyZXR1cm4gMDsKPiAgIH0KPiAgIAo+IC0jaWZkZWYgQ09ORklH X1BNCj4gLXN0YXRpYyBpbnQgdGVncmFfZGNfc3VzcGVuZChzdHJ1Y3QgZGV2aWNlICpkZXYpCj4g LXsKPiAtCXN0cnVjdCB0ZWdyYV9kYyAqZGMgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKPiAtCWlu dCBlcnI7Cj4gLQo+IC0JZXJyID0gcmVzZXRfY29udHJvbF9hc3NlcnQoZGMtPnJzdCk7Cj4gLQlp ZiAoZXJyIDwgMCkgewo+IC0JCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGFzc2VydCByZXNldDog JWRcbiIsIGVycik7Cj4gLQkJcmV0dXJuIGVycjsKPiAtCX0KPiAtCj4gLQlpZiAoZGMtPnNvYy0+ aGFzX3Bvd2VyZ2F0ZSkKPiAtCQl0ZWdyYV9wb3dlcmdhdGVfcG93ZXJfb2ZmKGRjLT5wb3dlcmdh dGUpOwo+IC0KPiAtCWNsa19kaXNhYmxlX3VucHJlcGFyZShkYy0+Y2xrKTsKPiAtCj4gLQlyZXR1 cm4gMDsKPiAtfQo+IC0KPiAtc3RhdGljIGludCB0ZWdyYV9kY19yZXN1bWUoc3RydWN0IGRldmlj ZSAqZGV2KQo+IC17Cj4gLQlzdHJ1Y3QgdGVncmFfZGMgKmRjID0gZGV2X2dldF9kcnZkYXRhKGRl dik7Cj4gLQlpbnQgZXJyOwo+IC0KPiAtCWlmIChkYy0+c29jLT5oYXNfcG93ZXJnYXRlKSB7Cj4g LQkJZXJyID0gdGVncmFfcG93ZXJnYXRlX3NlcXVlbmNlX3Bvd2VyX3VwKGRjLT5wb3dlcmdhdGUs IGRjLT5jbGssCj4gLQkJCQkJCQlkYy0+cnN0KTsKPiAtCQlpZiAoZXJyIDwgMCkgewo+IC0JCQlk ZXZfZXJyKGRldiwgImZhaWxlZCB0byBwb3dlciBwYXJ0aXRpb246ICVkXG4iLCBlcnIpOwo+IC0J CQlyZXR1cm4gZXJyOwo+IC0JCX0KPiAtCX0gZWxzZSB7Cj4gLQkJZXJyID0gY2xrX3ByZXBhcmVf ZW5hYmxlKGRjLT5jbGspOwo+IC0JCWlmIChlcnIgPCAwKSB7Cj4gLQkJCWRldl9lcnIoZGV2LCAi ZmFpbGVkIHRvIGVuYWJsZSBjbG9jazogJWRcbiIsIGVycik7Cj4gLQkJCXJldHVybiBlcnI7Cj4g LQkJfQo+IC0KPiAtCQllcnIgPSByZXNldF9jb250cm9sX2RlYXNzZXJ0KGRjLT5yc3QpOwo+IC0J CWlmIChlcnIgPCAwKSB7Cj4gLQkJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGRlYXNzZXJ0IHJl c2V0OiAlZFxuIiwgZXJyKTsKPiAtCQkJcmV0dXJuIGVycjsKPiAtCQl9Cj4gLQl9Cj4gLQo+IC0J cmV0dXJuIDA7Cj4gLX0KPiAtI2VuZGlmCj4gLQo+IC1zdGF0aWMgY29uc3Qgc3RydWN0IGRldl9w bV9vcHMgdGVncmFfZGNfcG1fb3BzID0gewo+IC0JU0VUX1JVTlRJTUVfUE1fT1BTKHRlZ3JhX2Rj X3N1c3BlbmQsIHRlZ3JhX2RjX3Jlc3VtZSwgTlVMTCkKPiAtfTsKPiAtCj4gICBzdHJ1Y3QgcGxh dGZvcm1fZHJpdmVyIHRlZ3JhX2RjX2RyaXZlciA9IHsKPiAgIAkuZHJpdmVyID0gewo+ICAgCQku bmFtZSA9ICJ0ZWdyYS1kYyIsCj4gICAJCS5vZl9tYXRjaF90YWJsZSA9IHRlZ3JhX2RjX29mX21h dGNoLAo+IC0JCS5wbSA9ICZ0ZWdyYV9kY19wbV9vcHMsCj4gICAJfSwKPiAgIAkucHJvYmUgPSB0 ZWdyYV9kY19wcm9iZSwKPiAgIAkucmVtb3ZlID0gdGVncmFfZGNfcmVtb3ZlLAo+IGRpZmYgLS1n aXQgYS9kcml2ZXJzL2dwdS9kcm0vdGVncmEvZHBhdXguYyBiL2RyaXZlcnMvZ3B1L2RybS90ZWdy YS9kcGF1eC5jCj4gaW5kZXggNjIyY2RmMWFkMjQ2Li43ZGZiNTBmNjUwNjcgMTAwNjQ0Cj4gLS0t IGEvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL2RwYXV4LmMKPiArKysgYi9kcml2ZXJzL2dwdS9kcm0v dGVncmEvZHBhdXguYwo+IEBAIC01ODgsNyArNTg4LDcgQEAgc3RhdGljIGludCB0ZWdyYV9kcGF1 eF9yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiAgIAkvKiBtYWtlIHN1cmUg cGFkcyBhcmUgcG93ZXJlZCBkb3duIHdoZW4gbm90IGluIHVzZSAqLwo+ICAgCXRlZ3JhX2RwYXV4 X3BhZF9wb3dlcl9kb3duKGRwYXV4KTsKPiAgIAo+IC0JcG1fcnVudGltZV9wdXQoJnBkZXYtPmRl dik7Cj4gKwlwbV9ydW50aW1lX3B1dF9zeW5jKCZwZGV2LT5kZXYpOwo+ICAgCXBtX3J1bnRpbWVf ZGlzYWJsZSgmcGRldi0+ZGV2KTsKPiAgIAo+ICAgCWRybV9kcF9hdXhfdW5yZWdpc3RlcigmZHBh dXgtPmF1eCk7Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS90ZWdyYS9kcm0uaCBiL2Ry aXZlcnMvZ3B1L2RybS90ZWdyYS9kcm0uaAo+IGluZGV4IGQ5NDE1NTNmN2EzZC4uZWQ5OWI2N2Rl YjI5IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS90ZWdyYS9kcm0uaAo+ICsrKyBiL2Ry aXZlcnMvZ3B1L2RybS90ZWdyYS9kcm0uaAo+IEBAIC0xNDQsNiArMTQ0LDggQEAgaW50IHRlZ3Jh X291dHB1dF9pbml0KHN0cnVjdCBkcm1fZGV2aWNlICpkcm0sIHN0cnVjdCB0ZWdyYV9vdXRwdXQg Km91dHB1dCk7Cj4gICB2b2lkIHRlZ3JhX291dHB1dF9leGl0KHN0cnVjdCB0ZWdyYV9vdXRwdXQg Km91dHB1dCk7Cj4gICB2b2lkIHRlZ3JhX291dHB1dF9maW5kX3Bvc3NpYmxlX2NydGNzKHN0cnVj dCB0ZWdyYV9vdXRwdXQgKm91dHB1dCwKPiAgIAkJCQkgICAgICBzdHJ1Y3QgZHJtX2RldmljZSAq ZHJtKTsKPiAraW50IHRlZ3JhX291dHB1dF9zdXNwZW5kKHN0cnVjdCB0ZWdyYV9vdXRwdXQgKm91 dHB1dCk7Cj4gK2ludCB0ZWdyYV9vdXRwdXRfcmVzdW1lKHN0cnVjdCB0ZWdyYV9vdXRwdXQgKm91 dHB1dCk7Cj4gICAKPiAgIGludCB0ZWdyYV9vdXRwdXRfY29ubmVjdG9yX2dldF9tb2RlcyhzdHJ1 Y3QgZHJtX2Nvbm5lY3RvciAqY29ubmVjdG9yKTsKPiAgIGVudW0gZHJtX2Nvbm5lY3Rvcl9zdGF0 dXMKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL2RzaS5jIGIvZHJpdmVycy9n cHUvZHJtL3RlZ3JhL2RzaS5jCj4gaW5kZXggZWM0NzVkMDIyZmEwLi44OGI5ZDY0Yzc3YmYgMTAw NjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL2RzaS5jCj4gKysrIGIvZHJpdmVycy9n cHUvZHJtL3RlZ3JhL2RzaS5jCj4gQEAgLTg0MCw3ICs4NDAsOSBAQCBzdGF0aWMgdm9pZCB0ZWdy YV9kc2lfdW5wcmVwYXJlKHN0cnVjdCB0ZWdyYV9kc2kgKmRzaSkKPiAgIAkJZGV2X2Vycihkc2kt PmRldiwgImZhaWxlZCB0byBkaXNhYmxlIE1JUEkgY2FsaWJyYXRpb246ICVkXG4iLAo+ICAgCQkJ ZXJyKTsKPiAgIAo+IC0JcG1fcnVudGltZV9wdXQoZHNpLT5kZXYpOwo+ICsJZXJyID0gaG9zdDF4 X2NsaWVudF9zdXNwZW5kKCZkc2ktPmNsaWVudCk7Cj4gKwlpZiAoZXJyIDwgMCkKPiArCQlkZXZf ZXJyKGRzaS0+ZGV2LCAiZmFpbGVkIHRvIHN1c3BlbmQ6ICVkXG4iLCBlcnIpOwo+ICAgfQo+ICAg Cj4gICBzdGF0aWMgdm9pZCB0ZWdyYV9kc2lfZW5jb2Rlcl9kaXNhYmxlKHN0cnVjdCBkcm1fZW5j b2RlciAqZW5jb2RlcikKPiBAQCAtODgyLDExICs4ODQsMTUgQEAgc3RhdGljIHZvaWQgdGVncmFf ZHNpX2VuY29kZXJfZGlzYWJsZShzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIpCj4gICAJdGVn cmFfZHNpX3VucHJlcGFyZShkc2kpOwo+ICAgfQo+ICAgCj4gLXN0YXRpYyB2b2lkIHRlZ3JhX2Rz aV9wcmVwYXJlKHN0cnVjdCB0ZWdyYV9kc2kgKmRzaSkKPiArc3RhdGljIGludCB0ZWdyYV9kc2lf cHJlcGFyZShzdHJ1Y3QgdGVncmFfZHNpICpkc2kpCj4gICB7Cj4gICAJaW50IGVycjsKPiAgIAo+ IC0JcG1fcnVudGltZV9nZXRfc3luYyhkc2ktPmRldik7Cj4gKwllcnIgPSBob3N0MXhfY2xpZW50 X3Jlc3VtZSgmZHNpLT5jbGllbnQpOwo+ICsJaWYgKGVyciA8IDApIHsKPiArCQlkZXZfZXJyKGRz aS0+ZGV2LCAiZmFpbGVkIHRvIHJlc3VtZTogJWRcbiIsIGVycik7Cj4gKwkJcmV0dXJuIGVycjsK PiArCX0KPiAgIAo+ICAgCWVyciA9IHRlZ3JhX21pcGlfZW5hYmxlKGRzaS0+bWlwaSk7Cj4gICAJ aWYgKGVyciA8IDApCj4gQEAgLTg5OSw2ICs5MDUsOCBAQCBzdGF0aWMgdm9pZCB0ZWdyYV9kc2lf cHJlcGFyZShzdHJ1Y3QgdGVncmFfZHNpICpkc2kpCj4gICAKPiAgIAlpZiAoZHNpLT5zbGF2ZSkK PiAgIAkJdGVncmFfZHNpX3ByZXBhcmUoZHNpLT5zbGF2ZSk7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4g ICB9Cj4gICAKPiAgIHN0YXRpYyB2b2lkIHRlZ3JhX2RzaV9lbmNvZGVyX2VuYWJsZShzdHJ1Y3Qg ZHJtX2VuY29kZXIgKmVuY29kZXIpCj4gQEAgLTkwOSw4ICs5MTcsMTMgQEAgc3RhdGljIHZvaWQg dGVncmFfZHNpX2VuY29kZXJfZW5hYmxlKHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlcikKPiAg IAlzdHJ1Y3QgdGVncmFfZHNpICpkc2kgPSB0b19kc2kob3V0cHV0KTsKPiAgIAlzdHJ1Y3QgdGVn cmFfZHNpX3N0YXRlICpzdGF0ZTsKPiAgIAl1MzIgdmFsdWU7Cj4gKwlpbnQgZXJyOwo+ICAgCj4g LQl0ZWdyYV9kc2lfcHJlcGFyZShkc2kpOwo+ICsJZXJyID0gdGVncmFfZHNpX3ByZXBhcmUoZHNp KTsKPiArCWlmIChlcnIgPCAwKSB7Cj4gKwkJZGV2X2Vycihkc2ktPmRldiwgImZhaWxlZCB0byBw cmVwYXJlOiAlZFxuIiwgZXJyKTsKPiArCQlyZXR1cm47Cj4gKwl9Cj4gICAKPiAgIAlzdGF0ZSA9 IHRlZ3JhX2RzaV9nZXRfc3RhdGUoZHNpKTsKPiAgIAo+IEBAIC0xMDc1LDkgKzEwODgsODkgQEAg c3RhdGljIGludCB0ZWdyYV9kc2lfZXhpdChzdHJ1Y3QgaG9zdDF4X2NsaWVudCAqY2xpZW50KQo+ ICAgCXJldHVybiAwOwo+ICAgfQo+ICAgCj4gK3N0YXRpYyBpbnQgdGVncmFfZHNpX3J1bnRpbWVf c3VzcGVuZChzdHJ1Y3QgaG9zdDF4X2NsaWVudCAqY2xpZW50KQo+ICt7Cj4gKwlzdHJ1Y3QgdGVn cmFfZHNpICpkc2kgPSBob3N0MXhfY2xpZW50X3RvX2RzaShjbGllbnQpOwo+ICsJc3RydWN0IGRl dmljZSAqZGV2ID0gY2xpZW50LT5kZXY7Cj4gKwlpbnQgZXJyOwo+ICsKPiArCWlmIChkc2ktPnJz dCkgewo+ICsJCWVyciA9IHJlc2V0X2NvbnRyb2xfYXNzZXJ0KGRzaS0+cnN0KTsKPiArCQlpZiAo ZXJyIDwgMCkgewo+ICsJCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBhc3NlcnQgcmVzZXQ6ICVk XG4iLCBlcnIpOwo+ICsJCQlyZXR1cm4gZXJyOwo+ICsJCX0KPiArCX0KPiArCj4gKwl1c2xlZXBf cmFuZ2UoMTAwMCwgMjAwMCk7Cj4gKwo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKGRzaS0+Y2xr X2xwKTsKPiArCWNsa19kaXNhYmxlX3VucHJlcGFyZShkc2ktPmNsayk7Cj4gKwo+ICsJcmVndWxh dG9yX2Rpc2FibGUoZHNpLT52ZGQpOwo+ICsJcG1fcnVudGltZV9wdXRfc3luYyhkZXYpOwo+ICsK PiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHRlZ3JhX2RzaV9ydW50aW1lX3Jl c3VtZShzdHJ1Y3QgaG9zdDF4X2NsaWVudCAqY2xpZW50KQo+ICt7Cj4gKwlzdHJ1Y3QgdGVncmFf ZHNpICpkc2kgPSBob3N0MXhfY2xpZW50X3RvX2RzaShjbGllbnQpOwo+ICsJc3RydWN0IGRldmlj ZSAqZGV2ID0gY2xpZW50LT5kZXY7Cj4gKwlpbnQgZXJyOwo+ICsKPiArCWVyciA9IHBtX3J1bnRp bWVfZ2V0X3N5bmMoZGV2KTsKPiArCWlmIChlcnIgPCAwKSB7Cj4gKwkJZGV2X2VycihkZXYsICJm YWlsZWQgdG8gZ2V0IHJ1bnRpbWUgUE06ICVkXG4iLCBlcnIpOwo+ICsJCXJldHVybiBlcnI7Cj4g Kwl9Cj4gKwo+ICsJZXJyID0gcmVndWxhdG9yX2VuYWJsZShkc2ktPnZkZCk7Cj4gKwlpZiAoZXJy IDwgMCkgewo+ICsJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGVuYWJsZSBWREQgc3VwcGx5OiAl ZFxuIiwgZXJyKTsKPiArCQlnb3RvIHB1dF9ycG07Cj4gKwl9Cj4gKwo+ICsJZXJyID0gY2xrX3By ZXBhcmVfZW5hYmxlKGRzaS0+Y2xrKTsKPiArCWlmIChlcnIgPCAwKSB7Cj4gKwkJZGV2X2Vycihk ZXYsICJjYW5ub3QgZW5hYmxlIERTSSBjbG9jazogJWRcbiIsIGVycik7Cj4gKwkJZ290byBkaXNh YmxlX3ZkZDsKPiArCX0KPiArCj4gKwllcnIgPSBjbGtfcHJlcGFyZV9lbmFibGUoZHNpLT5jbGtf bHApOwo+ICsJaWYgKGVyciA8IDApIHsKPiArCQlkZXZfZXJyKGRldiwgImNhbm5vdCBlbmFibGUg bG93LXBvd2VyIGNsb2NrOiAlZFxuIiwgZXJyKTsKPiArCQlnb3RvIGRpc2FibGVfY2xrOwo+ICsJ fQo+ICsKPiArCXVzbGVlcF9yYW5nZSgxMDAwLCAyMDAwKTsKPiArCj4gKwlpZiAoZHNpLT5yc3Qp IHsKPiArCQllcnIgPSByZXNldF9jb250cm9sX2RlYXNzZXJ0KGRzaS0+cnN0KTsKPiArCQlpZiAo ZXJyIDwgMCkgewo+ICsJCQlkZXZfZXJyKGRldiwgImNhbm5vdCBhc3NlcnQgcmVzZXQ6ICVkXG4i LCBlcnIpOwo+ICsJCQlnb3RvIGRpc2FibGVfY2xrX2xwOwo+ICsJCX0KPiArCX0KPiArCj4gKwly ZXR1cm4gMDsKPiArCj4gK2Rpc2FibGVfY2xrX2xwOgo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJl KGRzaS0+Y2xrX2xwKTsKPiArZGlzYWJsZV9jbGs6Cj4gKwljbGtfZGlzYWJsZV91bnByZXBhcmUo ZHNpLT5jbGspOwo+ICtkaXNhYmxlX3ZkZDoKPiArCXJlZ3VsYXRvcl9kaXNhYmxlKGRzaS0+dmRk KTsKPiArcHV0X3JwbToKPiArCXBtX3J1bnRpbWVfcHV0X3N5bmMoZGV2KTsKPiArCXJldHVybiBl cnI7Cj4gK30KPiArCj4gICBzdGF0aWMgY29uc3Qgc3RydWN0IGhvc3QxeF9jbGllbnRfb3BzIGRz aV9jbGllbnRfb3BzID0gewo+ICAgCS5pbml0ID0gdGVncmFfZHNpX2luaXQsCj4gICAJLmV4aXQg PSB0ZWdyYV9kc2lfZXhpdCwKPiArCS5zdXNwZW5kID0gdGVncmFfZHNpX3J1bnRpbWVfc3VzcGVu ZCwKPiArCS5yZXN1bWUgPSB0ZWdyYV9kc2lfcnVudGltZV9yZXN1bWUsCj4gICB9Owo+ICAgCj4g ICBzdGF0aWMgaW50IHRlZ3JhX2RzaV9zZXR1cF9jbG9ja3Moc3RydWN0IHRlZ3JhX2RzaSAqZHNp KQo+IEBAIC0xNTk2LDc5ICsxNjg5LDYgQEAgc3RhdGljIGludCB0ZWdyYV9kc2lfcmVtb3ZlKHN0 cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4gICAJcmV0dXJuIDA7Cj4gICB9Cj4gICAKPiAt I2lmZGVmIENPTkZJR19QTQo+IC1zdGF0aWMgaW50IHRlZ3JhX2RzaV9zdXNwZW5kKHN0cnVjdCBk ZXZpY2UgKmRldikKPiAtewo+IC0Jc3RydWN0IHRlZ3JhX2RzaSAqZHNpID0gZGV2X2dldF9kcnZk YXRhKGRldik7Cj4gLQlpbnQgZXJyOwo+IC0KPiAtCWlmIChkc2ktPnJzdCkgewo+IC0JCWVyciA9 IHJlc2V0X2NvbnRyb2xfYXNzZXJ0KGRzaS0+cnN0KTsKPiAtCQlpZiAoZXJyIDwgMCkgewo+IC0J CQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBhc3NlcnQgcmVzZXQ6ICVkXG4iLCBlcnIpOwo+IC0J CQlyZXR1cm4gZXJyOwo+IC0JCX0KPiAtCX0KPiAtCj4gLQl1c2xlZXBfcmFuZ2UoMTAwMCwgMjAw MCk7Cj4gLQo+IC0JY2xrX2Rpc2FibGVfdW5wcmVwYXJlKGRzaS0+Y2xrX2xwKTsKPiAtCWNsa19k aXNhYmxlX3VucHJlcGFyZShkc2ktPmNsayk7Cj4gLQo+IC0JcmVndWxhdG9yX2Rpc2FibGUoZHNp LT52ZGQpOwo+IC0KPiAtCXJldHVybiAwOwo+IC19Cj4gLQo+IC1zdGF0aWMgaW50IHRlZ3JhX2Rz aV9yZXN1bWUoc3RydWN0IGRldmljZSAqZGV2KQo+IC17Cj4gLQlzdHJ1Y3QgdGVncmFfZHNpICpk c2kgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKPiAtCWludCBlcnI7Cj4gLQo+IC0JZXJyID0gcmVn dWxhdG9yX2VuYWJsZShkc2ktPnZkZCk7Cj4gLQlpZiAoZXJyIDwgMCkgewo+IC0JCWRldl9lcnIo ZHNpLT5kZXYsICJmYWlsZWQgdG8gZW5hYmxlIFZERCBzdXBwbHk6ICVkXG4iLCBlcnIpOwo+IC0J CXJldHVybiBlcnI7Cj4gLQl9Cj4gLQo+IC0JZXJyID0gY2xrX3ByZXBhcmVfZW5hYmxlKGRzaS0+ Y2xrKTsKPiAtCWlmIChlcnIgPCAwKSB7Cj4gLQkJZGV2X2VycihkZXYsICJjYW5ub3QgZW5hYmxl IERTSSBjbG9jazogJWRcbiIsIGVycik7Cj4gLQkJZ290byBkaXNhYmxlX3ZkZDsKPiAtCX0KPiAt Cj4gLQllcnIgPSBjbGtfcHJlcGFyZV9lbmFibGUoZHNpLT5jbGtfbHApOwo+IC0JaWYgKGVyciA8 IDApIHsKPiAtCQlkZXZfZXJyKGRldiwgImNhbm5vdCBlbmFibGUgbG93LXBvd2VyIGNsb2NrOiAl ZFxuIiwgZXJyKTsKPiAtCQlnb3RvIGRpc2FibGVfY2xrOwo+IC0JfQo+IC0KPiAtCXVzbGVlcF9y YW5nZSgxMDAwLCAyMDAwKTsKPiAtCj4gLQlpZiAoZHNpLT5yc3QpIHsKPiAtCQllcnIgPSByZXNl dF9jb250cm9sX2RlYXNzZXJ0KGRzaS0+cnN0KTsKPiAtCQlpZiAoZXJyIDwgMCkgewo+IC0JCQlk ZXZfZXJyKGRldiwgImNhbm5vdCBhc3NlcnQgcmVzZXQ6ICVkXG4iLCBlcnIpOwo+IC0JCQlnb3Rv IGRpc2FibGVfY2xrX2xwOwo+IC0JCX0KPiAtCX0KPiAtCj4gLQlyZXR1cm4gMDsKPiAtCj4gLWRp c2FibGVfY2xrX2xwOgo+IC0JY2xrX2Rpc2FibGVfdW5wcmVwYXJlKGRzaS0+Y2xrX2xwKTsKPiAt ZGlzYWJsZV9jbGs6Cj4gLQljbGtfZGlzYWJsZV91bnByZXBhcmUoZHNpLT5jbGspOwo+IC1kaXNh YmxlX3ZkZDoKPiAtCXJlZ3VsYXRvcl9kaXNhYmxlKGRzaS0+dmRkKTsKPiAtCXJldHVybiBlcnI7 Cj4gLX0KPiAtI2VuZGlmCj4gLQo+IC1zdGF0aWMgY29uc3Qgc3RydWN0IGRldl9wbV9vcHMgdGVn cmFfZHNpX3BtX29wcyA9IHsKPiAtCVNFVF9SVU5USU1FX1BNX09QUyh0ZWdyYV9kc2lfc3VzcGVu ZCwgdGVncmFfZHNpX3Jlc3VtZSwgTlVMTCkKPiAtfTsKPiAtCj4gICBzdGF0aWMgY29uc3Qgc3Ry dWN0IG9mX2RldmljZV9pZCB0ZWdyYV9kc2lfb2ZfbWF0Y2hbXSA9IHsKPiAgIAl7IC5jb21wYXRp YmxlID0gIm52aWRpYSx0ZWdyYTIxMC1kc2kiLCB9LAo+ICAgCXsgLmNvbXBhdGlibGUgPSAibnZp ZGlhLHRlZ3JhMTMyLWRzaSIsIH0sCj4gQEAgLTE2ODIsNyArMTcwMiw2IEBAIHN0cnVjdCBwbGF0 Zm9ybV9kcml2ZXIgdGVncmFfZHNpX2RyaXZlciA9IHsKPiAgIAkuZHJpdmVyID0gewo+ICAgCQku bmFtZSA9ICJ0ZWdyYS1kc2kiLAo+ICAgCQkub2ZfbWF0Y2hfdGFibGUgPSB0ZWdyYV9kc2lfb2Zf bWF0Y2gsCj4gLQkJLnBtID0gJnRlZ3JhX2RzaV9wbV9vcHMsCj4gICAJfSwKPiAgIAkucHJvYmUg PSB0ZWdyYV9kc2lfcHJvYmUsCj4gICAJLnJlbW92ZSA9IHRlZ3JhX2RzaV9yZW1vdmUsCj4gZGlm ZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS90ZWdyYS9oZG1pLmMgYi9kcml2ZXJzL2dwdS9kcm0v dGVncmEvaGRtaS5jCj4gaW5kZXggMzhiZjFkMTYwOTVmLi5jYjUwNGVjOGYyODQgMTAwNjQ0Cj4g LS0tIGEvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL2hkbWkuYwo+ICsrKyBiL2RyaXZlcnMvZ3B1L2Ry bS90ZWdyYS9oZG1pLmMKPiBAQCAtMTE0Niw2ICsxMTQ2LDcgQEAgc3RhdGljIHZvaWQgdGVncmFf aGRtaV9lbmNvZGVyX2Rpc2FibGUoc3RydWN0IGRybV9lbmNvZGVyICplbmNvZGVyKQo+ICAgCXN0 cnVjdCB0ZWdyYV9kYyAqZGMgPSB0b190ZWdyYV9kYyhlbmNvZGVyLT5jcnRjKTsKPiAgIAlzdHJ1 Y3QgdGVncmFfaGRtaSAqaGRtaSA9IHRvX2hkbWkob3V0cHV0KTsKPiAgIAl1MzIgdmFsdWU7Cj4g KwlpbnQgZXJyOwo+ICAgCj4gICAJLyoKPiAgIAkgKiBUaGUgZm9sbG93aW5nIGFjY2Vzc2VzIHJl Z2lzdGVycyBvZiB0aGUgZGlzcGxheSBjb250cm9sbGVyLCBzbyBtYWtlCj4gQEAgLTExNzEsNyAr MTE3Miw5IEBAIHN0YXRpYyB2b2lkIHRlZ3JhX2hkbWlfZW5jb2Rlcl9kaXNhYmxlKHN0cnVjdCBk cm1fZW5jb2RlciAqZW5jb2RlcikKPiAgIAl0ZWdyYV9oZG1pX3dyaXRlbChoZG1pLCAwLCBIRE1J X05WX1BESVNQX0lOVF9FTkFCTEUpOwo+ICAgCXRlZ3JhX2hkbWlfd3JpdGVsKGhkbWksIDAsIEhE TUlfTlZfUERJU1BfSU5UX01BU0spOwo+ICAgCj4gLQlwbV9ydW50aW1lX3B1dChoZG1pLT5kZXYp Owo+ICsJZXJyID0gaG9zdDF4X2NsaWVudF9zdXNwZW5kKCZoZG1pLT5jbGllbnQpOwo+ICsJaWYg KGVyciA8IDApCj4gKwkJZGV2X2VycihoZG1pLT5kZXYsICJmYWlsZWQgdG8gc3VzcGVuZDogJWRc biIsIGVycik7Cj4gICB9Cj4gICAKPiAgIHN0YXRpYyB2b2lkIHRlZ3JhX2hkbWlfZW5jb2Rlcl9l bmFibGUoc3RydWN0IGRybV9lbmNvZGVyICplbmNvZGVyKQo+IEBAIC0xMTg2LDcgKzExODksMTEg QEAgc3RhdGljIHZvaWQgdGVncmFfaGRtaV9lbmNvZGVyX2VuYWJsZShzdHJ1Y3QgZHJtX2VuY29k ZXIgKmVuY29kZXIpCj4gICAJdTMyIHZhbHVlOwo+ICAgCWludCBlcnI7Cj4gICAKPiAtCXBtX3J1 bnRpbWVfZ2V0X3N5bmMoaGRtaS0+ZGV2KTsKPiArCWVyciA9IGhvc3QxeF9jbGllbnRfcmVzdW1l KCZoZG1pLT5jbGllbnQpOwo+ICsJaWYgKGVyciA8IDApIHsKPiArCQlkZXZfZXJyKGhkbWktPmRl diwgImZhaWxlZCB0byByZXN1bWU6ICVkXG4iLCBlcnIpOwo+ICsJCXJldHVybjsKPiArCX0KPiAg IAo+ICAgCS8qCj4gICAJICogRW5hYmxlIGFuZCB1bm1hc2sgdGhlIEhEQSBjb2RlYyBTQ1JBVENI MCByZWdpc3RlciBpbnRlcnJ1cHQuIFRoaXMKPiBAQCAtMTQ4OSw5ICsxNDk2LDY2IEBAIHN0YXRp YyBpbnQgdGVncmFfaGRtaV9leGl0KHN0cnVjdCBob3N0MXhfY2xpZW50ICpjbGllbnQpCj4gICAJ cmV0dXJuIDA7Cj4gICB9Cj4gICAKPiArc3RhdGljIGludCB0ZWdyYV9oZG1pX3J1bnRpbWVfc3Vz cGVuZChzdHJ1Y3QgaG9zdDF4X2NsaWVudCAqY2xpZW50KQo+ICt7Cj4gKwlzdHJ1Y3QgdGVncmFf aGRtaSAqaGRtaSA9IGhvc3QxeF9jbGllbnRfdG9faGRtaShjbGllbnQpOwo+ICsJc3RydWN0IGRl dmljZSAqZGV2ID0gY2xpZW50LT5kZXY7Cj4gKwlpbnQgZXJyOwo+ICsKPiArCWVyciA9IHJlc2V0 X2NvbnRyb2xfYXNzZXJ0KGhkbWktPnJzdCk7Cj4gKwlpZiAoZXJyIDwgMCkgewo+ICsJCWRldl9l cnIoZGV2LCAiZmFpbGVkIHRvIGFzc2VydCByZXNldDogJWRcbiIsIGVycik7Cj4gKwkJcmV0dXJu IGVycjsKPiArCX0KPiArCj4gKwl1c2xlZXBfcmFuZ2UoMTAwMCwgMjAwMCk7Cj4gKwo+ICsJY2xr X2Rpc2FibGVfdW5wcmVwYXJlKGhkbWktPmNsayk7Cj4gKwlwbV9ydW50aW1lX3B1dF9zeW5jKGRl dik7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgdGVncmFfaGRtaV9y dW50aW1lX3Jlc3VtZShzdHJ1Y3QgaG9zdDF4X2NsaWVudCAqY2xpZW50KQo+ICt7Cj4gKwlzdHJ1 Y3QgdGVncmFfaGRtaSAqaGRtaSA9IGhvc3QxeF9jbGllbnRfdG9faGRtaShjbGllbnQpOwo+ICsJ c3RydWN0IGRldmljZSAqZGV2ID0gY2xpZW50LT5kZXY7Cj4gKwlpbnQgZXJyOwo+ICsKPiArCWVy ciA9IHBtX3J1bnRpbWVfZ2V0X3N5bmMoZGV2KTsKPiArCWlmIChlcnIgPCAwKSB7Cj4gKwkJZGV2 X2VycihkZXYsICJmYWlsZWQgdG8gZ2V0IHJ1bnRpbWUgUE06ICVkXG4iLCBlcnIpOwo+ICsJCXJl dHVybiBlcnI7Cj4gKwl9Cj4gKwo+ICsJZXJyID0gY2xrX3ByZXBhcmVfZW5hYmxlKGhkbWktPmNs ayk7Cj4gKwlpZiAoZXJyIDwgMCkgewo+ICsJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGVuYWJs ZSBjbG9jazogJWRcbiIsIGVycik7Cj4gKwkJZ290byBwdXRfcnBtOwo+ICsJfQo+ICsKPiArCXVz bGVlcF9yYW5nZSgxMDAwLCAyMDAwKTsKPiArCj4gKwllcnIgPSByZXNldF9jb250cm9sX2RlYXNz ZXJ0KGhkbWktPnJzdCk7Cj4gKwlpZiAoZXJyIDwgMCkgewo+ICsJCWRldl9lcnIoZGV2LCAiZmFp bGVkIHRvIGRlYXNzZXJ0IHJlc2V0OiAlZFxuIiwgZXJyKTsKPiArCQlnb3RvIGRpc2FibGVfY2xr Owo+ICsJfQo+ICsKPiArCXJldHVybiAwOwo+ICsKPiArZGlzYWJsZV9jbGs6Cj4gKwljbGtfZGlz YWJsZV91bnByZXBhcmUoaGRtaS0+Y2xrKTsKPiArcHV0X3JwbToKPiArCXBtX3J1bnRpbWVfcHV0 X3N5bmMoZGV2KTsKPiArCXJldHVybiBlcnI7Cj4gK30KPiArCj4gICBzdGF0aWMgY29uc3Qgc3Ry dWN0IGhvc3QxeF9jbGllbnRfb3BzIGhkbWlfY2xpZW50X29wcyA9IHsKPiAgIAkuaW5pdCA9IHRl Z3JhX2hkbWlfaW5pdCwKPiAgIAkuZXhpdCA9IHRlZ3JhX2hkbWlfZXhpdCwKPiArCS5zdXNwZW5k ID0gdGVncmFfaGRtaV9ydW50aW1lX3N1c3BlbmQsCj4gKwkucmVzdW1lID0gdGVncmFfaGRtaV9y dW50aW1lX3Jlc3VtZSwKPiAgIH07Cj4gICAKPiAgIHN0YXRpYyBjb25zdCBzdHJ1Y3QgdGVncmFf aGRtaV9jb25maWcgdGVncmEyMF9oZG1pX2NvbmZpZyA9IHsKPiBAQCAtMTY5OSw1OCArMTc2Mywx MCBAQCBzdGF0aWMgaW50IHRlZ3JhX2hkbWlfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2Ug KnBkZXYpCj4gICAJcmV0dXJuIDA7Cj4gICB9Cj4gICAKPiAtI2lmZGVmIENPTkZJR19QTQo+IC1z dGF0aWMgaW50IHRlZ3JhX2hkbWlfc3VzcGVuZChzdHJ1Y3QgZGV2aWNlICpkZXYpCj4gLXsKPiAt CXN0cnVjdCB0ZWdyYV9oZG1pICpoZG1pID0gZGV2X2dldF9kcnZkYXRhKGRldik7Cj4gLQlpbnQg ZXJyOwo+IC0KPiAtCWVyciA9IHJlc2V0X2NvbnRyb2xfYXNzZXJ0KGhkbWktPnJzdCk7Cj4gLQlp ZiAoZXJyIDwgMCkgewo+IC0JCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGFzc2VydCByZXNldDog JWRcbiIsIGVycik7Cj4gLQkJcmV0dXJuIGVycjsKPiAtCX0KPiAtCj4gLQl1c2xlZXBfcmFuZ2Uo MTAwMCwgMjAwMCk7Cj4gLQo+IC0JY2xrX2Rpc2FibGVfdW5wcmVwYXJlKGhkbWktPmNsayk7Cj4g LQo+IC0JcmV0dXJuIDA7Cj4gLX0KPiAtCj4gLXN0YXRpYyBpbnQgdGVncmFfaGRtaV9yZXN1bWUo c3RydWN0IGRldmljZSAqZGV2KQo+IC17Cj4gLQlzdHJ1Y3QgdGVncmFfaGRtaSAqaGRtaSA9IGRl dl9nZXRfZHJ2ZGF0YShkZXYpOwo+IC0JaW50IGVycjsKPiAtCj4gLQllcnIgPSBjbGtfcHJlcGFy ZV9lbmFibGUoaGRtaS0+Y2xrKTsKPiAtCWlmIChlcnIgPCAwKSB7Cj4gLQkJZGV2X2VycihkZXYs ICJmYWlsZWQgdG8gZW5hYmxlIGNsb2NrOiAlZFxuIiwgZXJyKTsKPiAtCQlyZXR1cm4gZXJyOwo+ IC0JfQo+IC0KPiAtCXVzbGVlcF9yYW5nZSgxMDAwLCAyMDAwKTsKPiAtCj4gLQllcnIgPSByZXNl dF9jb250cm9sX2RlYXNzZXJ0KGhkbWktPnJzdCk7Cj4gLQlpZiAoZXJyIDwgMCkgewo+IC0JCWRl dl9lcnIoZGV2LCAiZmFpbGVkIHRvIGRlYXNzZXJ0IHJlc2V0OiAlZFxuIiwgZXJyKTsKPiAtCQlj bGtfZGlzYWJsZV91bnByZXBhcmUoaGRtaS0+Y2xrKTsKPiAtCQlyZXR1cm4gZXJyOwo+IC0JfQo+ IC0KPiAtCXJldHVybiAwOwo+IC19Cj4gLSNlbmRpZgo+IC0KPiAtc3RhdGljIGNvbnN0IHN0cnVj dCBkZXZfcG1fb3BzIHRlZ3JhX2hkbWlfcG1fb3BzID0gewo+IC0JU0VUX1JVTlRJTUVfUE1fT1BT KHRlZ3JhX2hkbWlfc3VzcGVuZCwgdGVncmFfaGRtaV9yZXN1bWUsIE5VTEwpCj4gLX07Cj4gLQo+ ICAgc3RydWN0IHBsYXRmb3JtX2RyaXZlciB0ZWdyYV9oZG1pX2RyaXZlciA9IHsKPiAgIAkuZHJp dmVyID0gewo+ICAgCQkubmFtZSA9ICJ0ZWdyYS1oZG1pIiwKPiAgIAkJLm9mX21hdGNoX3RhYmxl ID0gdGVncmFfaGRtaV9vZl9tYXRjaCwKPiAtCQkucG0gPSAmdGVncmFfaGRtaV9wbV9vcHMsCj4g ICAJfSwKPiAgIAkucHJvYmUgPSB0ZWdyYV9oZG1pX3Byb2JlLAo+ICAgCS5yZW1vdmUgPSB0ZWdy YV9oZG1pX3JlbW92ZSwKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL2h1Yi5j IGIvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL2h1Yi5jCj4gaW5kZXggNWM3NTQ1ZWU1YTViLi43M2U2 ZmU5YjgzM2QgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL2h1Yi5jCj4gKysr IGIvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL2h1Yi5jCj4gQEAgLTEwNSwxNyArMTA1LDI1IEBAIHN0 YXRpYyBpbmxpbmUgdm9pZCB0ZWdyYV9wbGFuZV93cml0ZWwoc3RydWN0IHRlZ3JhX3BsYW5lICpw bGFuZSwgdTMyIHZhbHVlLAo+ICAgCj4gICBzdGF0aWMgaW50IHRlZ3JhX3dpbmRvd2dyb3VwX2Vu YWJsZShzdHJ1Y3QgdGVncmFfd2luZG93Z3JvdXAgKndncnApCj4gICB7Cj4gKwlpbnQgZXJyID0g MDsKPiArCj4gICAJbXV0ZXhfbG9jaygmd2dycC0+bG9jayk7Cj4gICAKPiAgIAlpZiAod2dycC0+ dXNlY291bnQgPT0gMCkgewo+IC0JCXBtX3J1bnRpbWVfZ2V0X3N5bmMod2dycC0+cGFyZW50KTsK PiArCQllcnIgPSBob3N0MXhfY2xpZW50X3Jlc3VtZSh3Z3JwLT5wYXJlbnQpOwo+ICsJCWlmIChl cnIgPCAwKSB7Cj4gKwkJCWRldl9lcnIod2dycC0+cGFyZW50LT5kZXYsICJmYWlsZWQgdG8gcmVz dW1lOiAlZFxuIiwgZXJyKTsKPiArCQkJZ290byB1bmxvY2s7Cj4gKwkJfQo+ICsKPiAgIAkJcmVz ZXRfY29udHJvbF9kZWFzc2VydCh3Z3JwLT5yc3QpOwo+ICAgCX0KPiAgIAo+ICAgCXdncnAtPnVz ZWNvdW50Kys7Cj4gLQltdXRleF91bmxvY2soJndncnAtPmxvY2spOwo+ICAgCj4gLQlyZXR1cm4g MDsKPiArdW5sb2NrOgo+ICsJbXV0ZXhfdW5sb2NrKCZ3Z3JwLT5sb2NrKTsKPiArCXJldHVybiBl cnI7Cj4gICB9Cj4gICAKPiAgIHN0YXRpYyB2b2lkIHRlZ3JhX3dpbmRvd2dyb3VwX2Rpc2FibGUo c3RydWN0IHRlZ3JhX3dpbmRvd2dyb3VwICp3Z3JwKQo+IEBAIC0xMzEsNyArMTM5LDcgQEAgc3Rh dGljIHZvaWQgdGVncmFfd2luZG93Z3JvdXBfZGlzYWJsZShzdHJ1Y3QgdGVncmFfd2luZG93Z3Jv dXAgKndncnApCj4gICAJCQkgICAgICAgd2dycC0+aW5kZXgpOwo+ICAgCQl9Cj4gICAKPiAtCQlw bV9ydW50aW1lX3B1dCh3Z3JwLT5wYXJlbnQpOwo+ICsJCWhvc3QxeF9jbGllbnRfc3VzcGVuZCh3 Z3JwLT5wYXJlbnQpOwo+ICAgCX0KPiAgIAo+ICAgCXdncnAtPnVzZWNvdW50LS07Cj4gQEAgLTM4 OSw2ICszOTcsNyBAQCBzdGF0aWMgdm9pZCB0ZWdyYV9zaGFyZWRfcGxhbmVfYXRvbWljX2Rpc2Fi bGUoc3RydWN0IGRybV9wbGFuZSAqcGxhbmUsCj4gICAJc3RydWN0IHRlZ3JhX3BsYW5lICpwID0g dG9fdGVncmFfcGxhbmUocGxhbmUpOwo+ICAgCXN0cnVjdCB0ZWdyYV9kYyAqZGM7Cj4gICAJdTMy IHZhbHVlOwo+ICsJaW50IGVycjsKPiAgIAo+ICAgCS8qIHJpZW4gbmUgdmEgcGx1cyAqLwo+ICAg CWlmICghb2xkX3N0YXRlIHx8ICFvbGRfc3RhdGUtPmNydGMpCj4gQEAgLTM5Niw2ICs0MDUsMTIg QEAgc3RhdGljIHZvaWQgdGVncmFfc2hhcmVkX3BsYW5lX2F0b21pY19kaXNhYmxlKHN0cnVjdCBk cm1fcGxhbmUgKnBsYW5lLAo+ICAgCj4gICAJZGMgPSB0b190ZWdyYV9kYyhvbGRfc3RhdGUtPmNy dGMpOwo+ICAgCj4gKwllcnIgPSBob3N0MXhfY2xpZW50X3Jlc3VtZSgmZGMtPmNsaWVudCk7Cj4g KwlpZiAoZXJyIDwgMCkgewo+ICsJCWRldl9lcnIoZGMtPmRldiwgImZhaWxlZCB0byByZXN1bWU6 ICVkXG4iLCBlcnIpOwo+ICsJCXJldHVybjsKPiArCX0KPiArCj4gICAJLyoKPiAgIAkgKiBYWFgg TGVnYWN5IGhlbHBlcnMgc2VlbSB0byBzb21ldGltZXMgY2FsbCAtPmF0b21pY19kaXNhYmxlKCkg ZXZlbgo+ICAgCSAqIG9uIHBsYW5lcyB0aGF0IGFyZSBhbHJlYWR5IGRpc2FibGVkLiBNYWtlIHN1 cmUgd2UgZmFsbGJhY2sgdG8gdGhlCj4gQEAgLTQwNCwxNSArNDE5LDEzIEBAIHN0YXRpYyB2b2lk IHRlZ3JhX3NoYXJlZF9wbGFuZV9hdG9taWNfZGlzYWJsZShzdHJ1Y3QgZHJtX3BsYW5lICpwbGFu ZSwKPiAgIAlpZiAoV0FSTl9PTihwLT5kYyA9PSBOVUxMKSkKPiAgIAkJcC0+ZGMgPSBkYzsKPiAg IAo+IC0JcG1fcnVudGltZV9nZXRfc3luYyhkYy0+ZGV2KTsKPiAtCj4gICAJdmFsdWUgPSB0ZWdy YV9wbGFuZV9yZWFkbChwLCBEQ19XSU5fV0lOX09QVElPTlMpOwo+ICAgCXZhbHVlICY9IH5XSU5f RU5BQkxFOwo+ICAgCXRlZ3JhX3BsYW5lX3dyaXRlbChwLCB2YWx1ZSwgRENfV0lOX1dJTl9PUFRJ T05TKTsKPiAgIAo+ICAgCXRlZ3JhX2RjX3JlbW92ZV9zaGFyZWRfcGxhbmUoZGMsIHApOwo+ICAg Cj4gLQlwbV9ydW50aW1lX3B1dChkYy0+ZGV2KTsKPiArCWhvc3QxeF9jbGllbnRfc3VzcGVuZCgm ZGMtPmNsaWVudCk7Cj4gICB9Cj4gICAKPiAgIHN0YXRpYyB2b2lkIHRlZ3JhX3NoYXJlZF9wbGFu ZV9hdG9taWNfdXBkYXRlKHN0cnVjdCBkcm1fcGxhbmUgKnBsYW5lLAo+IEBAIC00MjUsNiArNDM4 LDcgQEAgc3RhdGljIHZvaWQgdGVncmFfc2hhcmVkX3BsYW5lX2F0b21pY191cGRhdGUoc3RydWN0 IGRybV9wbGFuZSAqcGxhbmUsCj4gICAJc3RydWN0IHRlZ3JhX3BsYW5lICpwID0gdG9fdGVncmFf cGxhbmUocGxhbmUpOwo+ICAgCWRtYV9hZGRyX3QgYmFzZTsKPiAgIAl1MzIgdmFsdWU7Cj4gKwlp bnQgZXJyOwo+ICAgCj4gICAJLyogcmllbiBuZSB2YSBwbHVzICovCj4gICAJaWYgKCFwbGFuZS0+ c3RhdGUtPmNydGMgfHwgIXBsYW5lLT5zdGF0ZS0+ZmIpCj4gQEAgLTQzNSw3ICs0NDksMTEgQEAg c3RhdGljIHZvaWQgdGVncmFfc2hhcmVkX3BsYW5lX2F0b21pY191cGRhdGUoc3RydWN0IGRybV9w bGFuZSAqcGxhbmUsCj4gICAJCXJldHVybjsKPiAgIAl9Cj4gICAKPiAtCXBtX3J1bnRpbWVfZ2V0 X3N5bmMoZGMtPmRldik7Cj4gKwllcnIgPSBob3N0MXhfY2xpZW50X3Jlc3VtZSgmZGMtPmNsaWVu dCk7Cj4gKwlpZiAoZXJyIDwgMCkgewo+ICsJCWRldl9lcnIoZGMtPmRldiwgImZhaWxlZCB0byBy ZXN1bWU6ICVkXG4iLCBlcnIpOwo+ICsJCXJldHVybjsKPiArCX0KPiAgIAo+ICAgCXRlZ3JhX2Rj X2Fzc2lnbl9zaGFyZWRfcGxhbmUoZGMsIHApOwo+ICAgCj4gQEAgLTUyNSw3ICs1NDMsNyBAQCBz dGF0aWMgdm9pZCB0ZWdyYV9zaGFyZWRfcGxhbmVfYXRvbWljX3VwZGF0ZShzdHJ1Y3QgZHJtX3Bs YW5lICpwbGFuZSwKPiAgIAl2YWx1ZSAmPSB+Q09OVFJPTF9DU0NfRU5BQkxFOwo+ICAgCXRlZ3Jh X3BsYW5lX3dyaXRlbChwLCB2YWx1ZSwgRENfV0lOX1dJTkRPV19TRVRfQ09OVFJPTCk7Cj4gICAK PiAtCXBtX3J1bnRpbWVfcHV0KGRjLT5kZXYpOwo+ICsJaG9zdDF4X2NsaWVudF9zdXNwZW5kKCZk Yy0+Y2xpZW50KTsKPiAgIH0KPiAgIAo+ICAgc3RhdGljIGNvbnN0IHN0cnVjdCBkcm1fcGxhbmVf aGVscGVyX2Z1bmNzIHRlZ3JhX3NoYXJlZF9wbGFuZV9oZWxwZXJfZnVuY3MgPSB7Cj4gQEAgLTU2 MSw3ICs1NzksNyBAQCBzdHJ1Y3QgZHJtX3BsYW5lICp0ZWdyYV9zaGFyZWRfcGxhbmVfY3JlYXRl KHN0cnVjdCBkcm1fZGV2aWNlICpkcm0sCj4gICAJcGxhbmUtPmJhc2UuaW5kZXggPSBpbmRleDsK PiAgIAo+ICAgCXBsYW5lLT53Z3JwID0gJmh1Yi0+d2dycHNbd2dycF07Cj4gLQlwbGFuZS0+d2dy cC0+cGFyZW50ID0gZGMtPmRldjsKPiArCXBsYW5lLT53Z3JwLT5wYXJlbnQgPSAmZGMtPmNsaWVu dDsKPiAgIAo+ICAgCXAgPSAmcGxhbmUtPmJhc2UuYmFzZTsKPiAgIAo+IEBAIC02NjYsOCArNjg0 LDEzIEBAIGludCB0ZWdyYV9kaXNwbGF5X2h1Yl9hdG9taWNfY2hlY2soc3RydWN0IGRybV9kZXZp Y2UgKmRybSwKPiAgIHN0YXRpYyB2b2lkIHRlZ3JhX2Rpc3BsYXlfaHViX3VwZGF0ZShzdHJ1Y3Qg dGVncmFfZGMgKmRjKQo+ICAgewo+ICAgCXUzMiB2YWx1ZTsKPiArCWludCBlcnI7Cj4gICAKPiAt CXBtX3J1bnRpbWVfZ2V0X3N5bmMoZGMtPmRldik7Cj4gKwllcnIgPSBob3N0MXhfY2xpZW50X3Jl c3VtZSgmZGMtPmNsaWVudCk7Cj4gKwlpZiAoZXJyIDwgMCkgewo+ICsJCWRldl9lcnIoZGMtPmRl diwgImZhaWxlZCB0byByZXN1bWU6ICVkXG4iLCBlcnIpOwo+ICsJCXJldHVybjsKPiArCX0KPiAg IAo+ICAgCXZhbHVlID0gdGVncmFfZGNfcmVhZGwoZGMsIERDX0NNRF9JSFVCX0NPTU1PTl9NSVND X0NUTCk7Cj4gICAJdmFsdWUgJj0gfkxBVEVOQ1lfRVZFTlQ7Cj4gQEAgLTY4Miw3ICs3MDUsNyBA QCBzdGF0aWMgdm9pZCB0ZWdyYV9kaXNwbGF5X2h1Yl91cGRhdGUoc3RydWN0IHRlZ3JhX2RjICpk YykKPiAgIAl0ZWdyYV9kY193cml0ZWwoZGMsIENPTU1PTl9BQ1RSRVEsIERDX0NNRF9TVEFURV9D T05UUk9MKTsKPiAgIAl0ZWdyYV9kY19yZWFkbChkYywgRENfQ01EX1NUQVRFX0NPTlRST0wpOwo+ ICAgCj4gLQlwbV9ydW50aW1lX3B1dChkYy0+ZGV2KTsKPiArCWhvc3QxeF9jbGllbnRfc3VzcGVu ZCgmZGMtPmNsaWVudCk7Cj4gICB9Cj4gICAKPiAgIHZvaWQgdGVncmFfZGlzcGxheV9odWJfYXRv bWljX2NvbW1pdChzdHJ1Y3QgZHJtX2RldmljZSAqZHJtLAo+IEBAIC03NDIsOSArNzY1LDg1IEBA IHN0YXRpYyBpbnQgdGVncmFfZGlzcGxheV9odWJfZXhpdChzdHJ1Y3QgaG9zdDF4X2NsaWVudCAq Y2xpZW50KQo+ICAgCXJldHVybiAwOwo+ICAgfQo+ICAgCj4gK3N0YXRpYyBpbnQgdGVncmFfZGlz cGxheV9odWJfcnVudGltZV9zdXNwZW5kKHN0cnVjdCBob3N0MXhfY2xpZW50ICpjbGllbnQpCj4g K3sKPiArCXN0cnVjdCB0ZWdyYV9kaXNwbGF5X2h1YiAqaHViID0gdG9fdGVncmFfZGlzcGxheV9o dWIoY2xpZW50KTsKPiArCXN0cnVjdCBkZXZpY2UgKmRldiA9IGNsaWVudC0+ZGV2Owo+ICsJdW5z aWduZWQgaW50IGkgPSBodWItPm51bV9oZWFkczsKPiArCWludCBlcnI7Cj4gKwo+ICsJZXJyID0g cmVzZXRfY29udHJvbF9hc3NlcnQoaHViLT5yc3QpOwo+ICsJaWYgKGVyciA8IDApCj4gKwkJcmV0 dXJuIGVycjsKPiArCj4gKwl3aGlsZSAoaS0tKQo+ICsJCWNsa19kaXNhYmxlX3VucHJlcGFyZSho dWItPmNsa19oZWFkc1tpXSk7Cj4gKwo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKGh1Yi0+Y2xr X2h1Yik7Cj4gKwljbGtfZGlzYWJsZV91bnByZXBhcmUoaHViLT5jbGtfZHNjKTsKPiArCWNsa19k aXNhYmxlX3VucHJlcGFyZShodWItPmNsa19kaXNwKTsKPiArCj4gKwlwbV9ydW50aW1lX3B1dF9z eW5jKGRldik7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgdGVncmFf ZGlzcGxheV9odWJfcnVudGltZV9yZXN1bWUoc3RydWN0IGhvc3QxeF9jbGllbnQgKmNsaWVudCkK PiArewo+ICsJc3RydWN0IHRlZ3JhX2Rpc3BsYXlfaHViICpodWIgPSB0b190ZWdyYV9kaXNwbGF5 X2h1YihjbGllbnQpOwo+ICsJc3RydWN0IGRldmljZSAqZGV2ID0gY2xpZW50LT5kZXY7Cj4gKwl1 bnNpZ25lZCBpbnQgaTsKPiArCWludCBlcnI7Cj4gKwo+ICsJZXJyID0gcG1fcnVudGltZV9nZXRf c3luYyhkZXYpOwo+ICsJaWYgKGVyciA8IDApIHsKPiArCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0 byBnZXQgcnVudGltZSBQTTogJWRcbiIsIGVycik7Cj4gKwkJcmV0dXJuIGVycjsKPiArCX0KPiAr Cj4gKwllcnIgPSBjbGtfcHJlcGFyZV9lbmFibGUoaHViLT5jbGtfZGlzcCk7Cj4gKwlpZiAoZXJy IDwgMCkKPiArCQlnb3RvIHB1dF9ycG07Cj4gKwo+ICsJZXJyID0gY2xrX3ByZXBhcmVfZW5hYmxl KGh1Yi0+Y2xrX2RzYyk7Cj4gKwlpZiAoZXJyIDwgMCkKPiArCQlnb3RvIGRpc2FibGVfZGlzcDsK PiArCj4gKwllcnIgPSBjbGtfcHJlcGFyZV9lbmFibGUoaHViLT5jbGtfaHViKTsKPiArCWlmIChl cnIgPCAwKQo+ICsJCWdvdG8gZGlzYWJsZV9kc2M7Cj4gKwo+ICsJZm9yIChpID0gMDsgaSA8IGh1 Yi0+bnVtX2hlYWRzOyBpKyspIHsKPiArCQllcnIgPSBjbGtfcHJlcGFyZV9lbmFibGUoaHViLT5j bGtfaGVhZHNbaV0pOwo+ICsJCWlmIChlcnIgPCAwKQo+ICsJCQlnb3RvIGRpc2FibGVfaGVhZHM7 Cj4gKwl9Cj4gKwo+ICsJZXJyID0gcmVzZXRfY29udHJvbF9kZWFzc2VydChodWItPnJzdCk7Cj4g KwlpZiAoZXJyIDwgMCkKPiArCQlnb3RvIGRpc2FibGVfaGVhZHM7Cj4gKwo+ICsJcmV0dXJuIDA7 Cj4gKwo+ICtkaXNhYmxlX2hlYWRzOgo+ICsJd2hpbGUgKGktLSkKPiArCQljbGtfZGlzYWJsZV91 bnByZXBhcmUoaHViLT5jbGtfaGVhZHNbaV0pOwo+ICsKPiArCWNsa19kaXNhYmxlX3VucHJlcGFy ZShodWItPmNsa19odWIpOwo+ICtkaXNhYmxlX2RzYzoKPiArCWNsa19kaXNhYmxlX3VucHJlcGFy ZShodWItPmNsa19kc2MpOwo+ICtkaXNhYmxlX2Rpc3A6Cj4gKwljbGtfZGlzYWJsZV91bnByZXBh cmUoaHViLT5jbGtfZGlzcCk7Cj4gK3B1dF9ycG06Cj4gKwlwbV9ydW50aW1lX3B1dF9zeW5jKGRl dik7Cj4gKwlyZXR1cm4gZXJyOwo+ICt9Cj4gKwo+ICAgc3RhdGljIGNvbnN0IHN0cnVjdCBob3N0 MXhfY2xpZW50X29wcyB0ZWdyYV9kaXNwbGF5X2h1Yl9vcHMgPSB7Cj4gICAJLmluaXQgPSB0ZWdy YV9kaXNwbGF5X2h1Yl9pbml0LAo+ICAgCS5leGl0ID0gdGVncmFfZGlzcGxheV9odWJfZXhpdCwK PiArCS5zdXNwZW5kID0gdGVncmFfZGlzcGxheV9odWJfcnVudGltZV9zdXNwZW5kLAo+ICsJLnJl c3VtZSA9IHRlZ3JhX2Rpc3BsYXlfaHViX3J1bnRpbWVfcmVzdW1lLAo+ICAgfTsKPiAgIAo+ICAg c3RhdGljIGludCB0ZWdyYV9kaXNwbGF5X2h1Yl9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNl ICpwZGV2KQo+IEBAIC04NjEsNiArOTYwLDcgQEAgc3RhdGljIGludCB0ZWdyYV9kaXNwbGF5X2h1 Yl9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+ICAgc3RhdGljIGludCB0ZWdy YV9kaXNwbGF5X2h1Yl9yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiAgIHsK PiAgIAlzdHJ1Y3QgdGVncmFfZGlzcGxheV9odWIgKmh1YiA9IHBsYXRmb3JtX2dldF9kcnZkYXRh KHBkZXYpOwo+ICsJdW5zaWduZWQgaW50IGk7Cj4gICAJaW50IGVycjsKPiAgIAo+ICAgCWVyciA9 IGhvc3QxeF9jbGllbnRfdW5yZWdpc3RlcigmaHViLT5jbGllbnQpOwo+IEBAIC04NjksNzggKzk2 OSwxNyBAQCBzdGF0aWMgaW50IHRlZ3JhX2Rpc3BsYXlfaHViX3JlbW92ZShzdHJ1Y3QgcGxhdGZv cm1fZGV2aWNlICpwZGV2KQo+ICAgCQkJZXJyKTsKPiAgIAl9Cj4gICAKPiAtCXBtX3J1bnRpbWVf ZGlzYWJsZSgmcGRldi0+ZGV2KTsKPiAtCj4gLQlyZXR1cm4gZXJyOwo+IC19Cj4gLQo+IC1zdGF0 aWMgaW50IF9fbWF5YmVfdW51c2VkIHRlZ3JhX2Rpc3BsYXlfaHViX3N1c3BlbmQoc3RydWN0IGRl dmljZSAqZGV2KQo+IC17Cj4gLQlzdHJ1Y3QgdGVncmFfZGlzcGxheV9odWIgKmh1YiA9IGRldl9n ZXRfZHJ2ZGF0YShkZXYpOwo+IC0JdW5zaWduZWQgaW50IGkgPSBodWItPm51bV9oZWFkczsKPiAt CWludCBlcnI7Cj4gLQo+IC0JZXJyID0gcmVzZXRfY29udHJvbF9hc3NlcnQoaHViLT5yc3QpOwo+ IC0JaWYgKGVyciA8IDApCj4gLQkJcmV0dXJuIGVycjsKPiAtCj4gLQl3aGlsZSAoaS0tKQo+IC0J CWNsa19kaXNhYmxlX3VucHJlcGFyZShodWItPmNsa19oZWFkc1tpXSk7Cj4gLQo+IC0JY2xrX2Rp c2FibGVfdW5wcmVwYXJlKGh1Yi0+Y2xrX2h1Yik7Cj4gLQljbGtfZGlzYWJsZV91bnByZXBhcmUo aHViLT5jbGtfZHNjKTsKPiAtCWNsa19kaXNhYmxlX3VucHJlcGFyZShodWItPmNsa19kaXNwKTsK PiAtCj4gLQlyZXR1cm4gMDsKPiAtfQo+IC0KPiAtc3RhdGljIGludCBfX21heWJlX3VudXNlZCB0 ZWdyYV9kaXNwbGF5X2h1Yl9yZXN1bWUoc3RydWN0IGRldmljZSAqZGV2KQo+IC17Cj4gLQlzdHJ1 Y3QgdGVncmFfZGlzcGxheV9odWIgKmh1YiA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwo+IC0JdW5z aWduZWQgaW50IGk7Cj4gLQlpbnQgZXJyOwo+IC0KPiAtCWVyciA9IGNsa19wcmVwYXJlX2VuYWJs ZShodWItPmNsa19kaXNwKTsKPiAtCWlmIChlcnIgPCAwKQo+IC0JCXJldHVybiBlcnI7Cj4gLQo+ IC0JZXJyID0gY2xrX3ByZXBhcmVfZW5hYmxlKGh1Yi0+Y2xrX2RzYyk7Cj4gLQlpZiAoZXJyIDwg MCkKPiAtCQlnb3RvIGRpc2FibGVfZGlzcDsKPiAtCj4gLQllcnIgPSBjbGtfcHJlcGFyZV9lbmFi bGUoaHViLT5jbGtfaHViKTsKPiAtCWlmIChlcnIgPCAwKQo+IC0JCWdvdG8gZGlzYWJsZV9kc2M7 Cj4gKwlmb3IgKGkgPSAwOyBpIDwgaHViLT5zb2MtPm51bV93Z3JwczsgaSsrKSB7Cj4gKwkJc3Ry dWN0IHRlZ3JhX3dpbmRvd2dyb3VwICp3Z3JwID0gJmh1Yi0+d2dycHNbaV07Cj4gICAKPiAtCWZv ciAoaSA9IDA7IGkgPCBodWItPm51bV9oZWFkczsgaSsrKSB7Cj4gLQkJZXJyID0gY2xrX3ByZXBh cmVfZW5hYmxlKGh1Yi0+Y2xrX2hlYWRzW2ldKTsKPiAtCQlpZiAoZXJyIDwgMCkKPiAtCQkJZ290 byBkaXNhYmxlX2hlYWRzOwo+ICsJCW11dGV4X2Rlc3Ryb3koJndncnAtPmxvY2spOwo+ICAgCX0K PiAgIAo+IC0JZXJyID0gcmVzZXRfY29udHJvbF9kZWFzc2VydChodWItPnJzdCk7Cj4gLQlpZiAo ZXJyIDwgMCkKPiAtCQlnb3RvIGRpc2FibGVfaGVhZHM7Cj4gLQo+IC0JcmV0dXJuIDA7Cj4gLQo+ IC1kaXNhYmxlX2hlYWRzOgo+IC0Jd2hpbGUgKGktLSkKPiAtCQljbGtfZGlzYWJsZV91bnByZXBh cmUoaHViLT5jbGtfaGVhZHNbaV0pOwo+ICsJcG1fcnVudGltZV9kaXNhYmxlKCZwZGV2LT5kZXYp Owo+ICAgCj4gLQljbGtfZGlzYWJsZV91bnByZXBhcmUoaHViLT5jbGtfaHViKTsKPiAtZGlzYWJs ZV9kc2M6Cj4gLQljbGtfZGlzYWJsZV91bnByZXBhcmUoaHViLT5jbGtfZHNjKTsKPiAtZGlzYWJs ZV9kaXNwOgo+IC0JY2xrX2Rpc2FibGVfdW5wcmVwYXJlKGh1Yi0+Y2xrX2Rpc3ApOwo+ICAgCXJl dHVybiBlcnI7Cj4gICB9Cj4gICAKPiAtc3RhdGljIGNvbnN0IHN0cnVjdCBkZXZfcG1fb3BzIHRl Z3JhX2Rpc3BsYXlfaHViX3BtX29wcyA9IHsKPiAtCVNFVF9SVU5USU1FX1BNX09QUyh0ZWdyYV9k aXNwbGF5X2h1Yl9zdXNwZW5kLAo+IC0JCQkgICB0ZWdyYV9kaXNwbGF5X2h1Yl9yZXN1bWUsIE5V TEwpCj4gLX07Cj4gLQo+ICAgc3RhdGljIGNvbnN0IHN0cnVjdCB0ZWdyYV9kaXNwbGF5X2h1Yl9z b2MgdGVncmExODZfZGlzcGxheV9odWIgPSB7Cj4gICAJLm51bV93Z3JwcyA9IDYsCj4gICAJLnN1 cHBvcnRzX2RzYyA9IHRydWUsCj4gQEAgLTk2OCw3ICsxMDA3LDYgQEAgc3RydWN0IHBsYXRmb3Jt X2RyaXZlciB0ZWdyYV9kaXNwbGF5X2h1Yl9kcml2ZXIgPSB7Cj4gICAJLmRyaXZlciA9IHsKPiAg IAkJLm5hbWUgPSAidGVncmEtZGlzcGxheS1odWIiLAo+ICAgCQkub2ZfbWF0Y2hfdGFibGUgPSB0 ZWdyYV9kaXNwbGF5X2h1Yl9vZl9tYXRjaCwKPiAtCQkucG0gPSAmdGVncmFfZGlzcGxheV9odWJf cG1fb3BzLAo+ICAgCX0sCj4gICAJLnByb2JlID0gdGVncmFfZGlzcGxheV9odWJfcHJvYmUsCj4g ICAJLnJlbW92ZSA9IHRlZ3JhX2Rpc3BsYXlfaHViX3JlbW92ZSwKPiBkaWZmIC0tZ2l0IGEvZHJp dmVycy9ncHUvZHJtL3RlZ3JhL2h1Yi5oIGIvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL2h1Yi5oCj4g aW5kZXggNzY3YTYwZDkzMTNjLi4zZWZhMWJlMDdmZjggMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9n cHUvZHJtL3RlZ3JhL2h1Yi5oCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL2h1Yi5oCj4g QEAgLTE3LDcgKzE3LDcgQEAgc3RydWN0IHRlZ3JhX3dpbmRvd2dyb3VwIHsKPiAgIAlzdHJ1Y3Qg bXV0ZXggbG9jazsKPiAgIAo+ICAgCXVuc2lnbmVkIGludCBpbmRleDsKPiAtCXN0cnVjdCBkZXZp Y2UgKnBhcmVudDsKPiArCXN0cnVjdCBob3N0MXhfY2xpZW50ICpwYXJlbnQ7Cj4gICAJc3RydWN0 IHJlc2V0X2NvbnRyb2wgKnJzdDsKPiAgIH07Cj4gICAKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9n cHUvZHJtL3RlZ3JhL3Nvci5jIGIvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL3Nvci5jCj4gaW5kZXgg OTU2YmY1ZDY4MGFkLi4yMDBkOTllMTdhZmUgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJt L3RlZ3JhL3Nvci5jCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL3Nvci5jCj4gQEAgLTIy NTUsNyArMjI1NSw3IEBAIHN0YXRpYyB2b2lkIHRlZ3JhX3Nvcl9oZG1pX2Rpc2FibGUoc3RydWN0 IGRybV9lbmNvZGVyICplbmNvZGVyKQo+ICAgCWlmIChlcnIgPCAwKQo+ICAgCQlkZXZfZXJyKHNv ci0+ZGV2LCAiZmFpbGVkIHRvIHBvd2VyIG9mZiBJL08gcGFkOiAlZFxuIiwgZXJyKTsKPiAgIAo+ IC0JcG1fcnVudGltZV9wdXQoc29yLT5kZXYpOwo+ICsJaG9zdDF4X2NsaWVudF9zdXNwZW5kKCZz b3ItPmNsaWVudCk7Cj4gICB9Cj4gICAKPiAgIHN0YXRpYyB2b2lkIHRlZ3JhX3Nvcl9oZG1pX2Vu YWJsZShzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIpCj4gQEAgLTIyNzYsNyArMjI3NiwxMSBA QCBzdGF0aWMgdm9pZCB0ZWdyYV9zb3JfaGRtaV9lbmFibGUoc3RydWN0IGRybV9lbmNvZGVyICpl bmNvZGVyKQo+ICAgCW1vZGUgPSAmZW5jb2Rlci0+Y3J0Yy0+c3RhdGUtPmFkanVzdGVkX21vZGU7 Cj4gICAJcGNsayA9IG1vZGUtPmNsb2NrICogMTAwMDsKPiAgIAo+IC0JcG1fcnVudGltZV9nZXRf c3luYyhzb3ItPmRldik7Cj4gKwllcnIgPSBob3N0MXhfY2xpZW50X3Jlc3VtZSgmc29yLT5jbGll bnQpOwo+ICsJaWYgKGVyciA8IDApIHsKPiArCQlkZXZfZXJyKHNvci0+ZGV2LCAiZmFpbGVkIHRv IHJlc3VtZTogJWRcbiIsIGVycik7Cj4gKwkJcmV0dXJuOwo+ICsJfQo+ICAgCj4gICAJLyogc3dp dGNoIHRvIHNhZmUgcGFyZW50IGNsb2NrICovCj4gICAJZXJyID0gdGVncmFfc29yX3NldF9wYXJl bnRfY2xvY2soc29yLCBzb3ItPmNsa19zYWZlKTsKPiBAQCAtMjcyMiw3ICsyNzI2LDcgQEAgc3Rh dGljIHZvaWQgdGVncmFfc29yX2RwX2Rpc2FibGUoc3RydWN0IGRybV9lbmNvZGVyICplbmNvZGVy KQo+ICAgCWlmIChvdXRwdXQtPnBhbmVsKQo+ICAgCQlkcm1fcGFuZWxfdW5wcmVwYXJlKG91dHB1 dC0+cGFuZWwpOwo+ICAgCj4gLQlwbV9ydW50aW1lX3B1dChzb3ItPmRldik7Cj4gKwlob3N0MXhf Y2xpZW50X3N1c3BlbmQoJnNvci0+Y2xpZW50KTsKPiAgIH0KPiAgIAo+ICAgc3RhdGljIHZvaWQg dGVncmFfc29yX2RwX2VuYWJsZShzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIpCj4gQEAgLTI3 NDIsNyArMjc0NiwxMSBAQCBzdGF0aWMgdm9pZCB0ZWdyYV9zb3JfZHBfZW5hYmxlKHN0cnVjdCBk cm1fZW5jb2RlciAqZW5jb2RlcikKPiAgIAltb2RlID0gJmVuY29kZXItPmNydGMtPnN0YXRlLT5h ZGp1c3RlZF9tb2RlOwo+ICAgCWluZm8gPSAmb3V0cHV0LT5jb25uZWN0b3IuZGlzcGxheV9pbmZv Owo+ICAgCj4gLQlwbV9ydW50aW1lX2dldF9zeW5jKHNvci0+ZGV2KTsKPiArCWVyciA9IGhvc3Qx eF9jbGllbnRfcmVzdW1lKCZzb3ItPmNsaWVudCk7Cj4gKwlpZiAoZXJyIDwgMCkgewo+ICsJCWRl dl9lcnIoc29yLT5kZXYsICJmYWlsZWQgdG8gcmVzdW1lOiAlZFxuIiwgZXJyKTsKPiArCQlyZXR1 cm47Cj4gKwl9Cj4gICAKPiAgIAkvKiBzd2l0Y2ggdG8gc2FmZSBwYXJlbnQgY2xvY2sgKi8KPiAg IAllcnIgPSB0ZWdyYV9zb3Jfc2V0X3BhcmVudF9jbG9jayhzb3IsIHNvci0+Y2xrX3NhZmUpOwo+ IEBAIC0zMTg5LDkgKzMxOTcsODAgQEAgc3RhdGljIGludCB0ZWdyYV9zb3JfZXhpdChzdHJ1Y3Qg aG9zdDF4X2NsaWVudCAqY2xpZW50KQo+ICAgCXJldHVybiAwOwo+ICAgfQo+ICAgCj4gK3N0YXRp YyBpbnQgdGVncmFfc29yX3J1bnRpbWVfc3VzcGVuZChzdHJ1Y3QgaG9zdDF4X2NsaWVudCAqY2xp ZW50KQo+ICt7Cj4gKwlzdHJ1Y3QgdGVncmFfc29yICpzb3IgPSBob3N0MXhfY2xpZW50X3RvX3Nv cihjbGllbnQpOwo+ICsJc3RydWN0IGRldmljZSAqZGV2ID0gY2xpZW50LT5kZXY7Cj4gKwlpbnQg ZXJyOwo+ICsKPiArCWlmIChzb3ItPnJzdCkgewo+ICsJCWVyciA9IHJlc2V0X2NvbnRyb2xfYXNz ZXJ0KHNvci0+cnN0KTsKPiArCQlpZiAoZXJyIDwgMCkgewo+ICsJCQlkZXZfZXJyKGRldiwgImZh aWxlZCB0byBhc3NlcnQgcmVzZXQ6ICVkXG4iLCBlcnIpOwo+ICsJCQlyZXR1cm4gZXJyOwo+ICsJ CX0KPiArCj4gKwkJcmVzZXRfY29udHJvbF9yZWxlYXNlKHNvci0+cnN0KTsKPiArCX0KPiArCj4g Kwl1c2xlZXBfcmFuZ2UoMTAwMCwgMjAwMCk7Cj4gKwo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJl KHNvci0+Y2xrKTsKPiArCXBtX3J1bnRpbWVfcHV0X3N5bmMoZGV2KTsKPiArCj4gKwlyZXR1cm4g MDsKPiArfQo+ICsKPiArc3RhdGljIGludCB0ZWdyYV9zb3JfcnVudGltZV9yZXN1bWUoc3RydWN0 IGhvc3QxeF9jbGllbnQgKmNsaWVudCkKPiArewo+ICsJc3RydWN0IHRlZ3JhX3NvciAqc29yID0g aG9zdDF4X2NsaWVudF90b19zb3IoY2xpZW50KTsKPiArCXN0cnVjdCBkZXZpY2UgKmRldiA9IGNs aWVudC0+ZGV2Owo+ICsJaW50IGVycjsKPiArCj4gKwllcnIgPSBwbV9ydW50aW1lX2dldF9zeW5j KGRldik7Cj4gKwlpZiAoZXJyIDwgMCkgewo+ICsJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGdl dCBydW50aW1lIFBNOiAlZFxuIiwgZXJyKTsKPiArCQlyZXR1cm4gZXJyOwo+ICsJfQo+ICsKPiAr CWVyciA9IGNsa19wcmVwYXJlX2VuYWJsZShzb3ItPmNsayk7Cj4gKwlpZiAoZXJyIDwgMCkgewo+ ICsJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGVuYWJsZSBjbG9jazogJWRcbiIsIGVycik7Cj4g KwkJZ290byBwdXRfcnBtOwo+ICsJfQo+ICsKPiArCXVzbGVlcF9yYW5nZSgxMDAwLCAyMDAwKTsK PiArCj4gKwlpZiAoc29yLT5yc3QpIHsKPiArCQllcnIgPSByZXNldF9jb250cm9sX2FjcXVpcmUo c29yLT5yc3QpOwo+ICsJCWlmIChlcnIgPCAwKSB7Cj4gKwkJCWRldl9lcnIoZGV2LCAiZmFpbGVk IHRvIGFjcXVpcmUgcmVzZXQ6ICVkXG4iLCBlcnIpOwo+ICsJCQlnb3RvIGRpc2FibGVfY2xrOwo+ ICsJCX0KPiArCj4gKwkJZXJyID0gcmVzZXRfY29udHJvbF9kZWFzc2VydChzb3ItPnJzdCk7Cj4g KwkJaWYgKGVyciA8IDApIHsKPiArCQkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gZGVhc3NlcnQg cmVzZXQ6ICVkXG4iLCBlcnIpOwo+ICsJCQlnb3RvIHJlbGVhc2VfcmVzZXQ7Cj4gKwkJfQo+ICsJ fQo+ICsKPiArCXJldHVybiAwOwo+ICsKPiArcmVsZWFzZV9yZXNldDoKPiArCXJlc2V0X2NvbnRy b2xfcmVsZWFzZShzb3ItPnJzdCk7Cj4gK2Rpc2FibGVfY2xrOgo+ICsJY2xrX2Rpc2FibGVfdW5w cmVwYXJlKHNvci0+Y2xrKTsKPiArcHV0X3JwbToKPiArCXBtX3J1bnRpbWVfcHV0X3N5bmMoZGV2 KTsKPiArCXJldHVybiBlcnI7Cj4gK30KPiArCj4gICBzdGF0aWMgY29uc3Qgc3RydWN0IGhvc3Qx eF9jbGllbnRfb3BzIHNvcl9jbGllbnRfb3BzID0gewo+ICAgCS5pbml0ID0gdGVncmFfc29yX2lu aXQsCj4gICAJLmV4aXQgPSB0ZWdyYV9zb3JfZXhpdCwKPiArCS5zdXNwZW5kID0gdGVncmFfc29y X3J1bnRpbWVfc3VzcGVuZCwKPiArCS5yZXN1bWUgPSB0ZWdyYV9zb3JfcnVudGltZV9yZXN1bWUs Cj4gICB9Owo+ICAgCj4gICBzdGF0aWMgY29uc3QgdTggdGVncmExMjRfc29yX3hiYXJfY2ZnWzVd ID0gewo+IEBAIC0zODQyLDEwICszOTIxLDkgQEAgc3RhdGljIGludCB0ZWdyYV9zb3JfcHJvYmUo c3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiAgIAlpZiAoIXNvci0+Y2xrX3BhZCkgewo+ ICAgCQljaGFyICpuYW1lOwo+ICAgCj4gLQkJZXJyID0gcG1fcnVudGltZV9nZXRfc3luYygmcGRl di0+ZGV2KTsKPiArCQllcnIgPSBob3N0MXhfY2xpZW50X3Jlc3VtZSgmc29yLT5jbGllbnQpOwo+ ICAgCQlpZiAoZXJyIDwgMCkgewo+IC0JCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJmYWlsZWQgdG8g Z2V0IHJ1bnRpbWUgUE06ICVkXG4iLAo+IC0JCQkJZXJyKTsKPiArCQkJZGV2X2Vycihzb3ItPmRl diwgImZhaWxlZCB0byByZXN1bWU6ICVkXG4iLCBlcnIpOwo+ICAgCQkJZ290byByZW1vdmU7Cj4g ICAJCX0KPiAgIAo+IEBAIC0zODU2LDcgKzM5MzQsNyBAQCBzdGF0aWMgaW50IHRlZ3JhX3Nvcl9w cm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+ICAgCQl9Cj4gICAKPiAgIAkJc29y LT5jbGtfcGFkID0gdGVncmFfY2xrX3Nvcl9wYWRfcmVnaXN0ZXIoc29yLCBuYW1lKTsKPiAtCQlw bV9ydW50aW1lX3B1dCgmcGRldi0+ZGV2KTsKPiArCQlob3N0MXhfY2xpZW50X3N1c3BlbmQoJnNv ci0+Y2xpZW50KTsKPiAgIAl9Cj4gICAKPiAgIAlpZiAoSVNfRVJSKHNvci0+Y2xrX3BhZCkpIHsK PiBAQCAtMzkxMiw2MSArMzk5MCw2IEBAIHN0YXRpYyBpbnQgdGVncmFfc29yX3JlbW92ZShzdHJ1 Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+ICAgCXJldHVybiAwOwo+ICAgfQo+ICAgCj4gLXN0 YXRpYyBpbnQgdGVncmFfc29yX3J1bnRpbWVfc3VzcGVuZChzdHJ1Y3QgZGV2aWNlICpkZXYpCj4g LXsKPiAtCXN0cnVjdCB0ZWdyYV9zb3IgKnNvciA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwo+IC0J aW50IGVycjsKPiAtCj4gLQlpZiAoc29yLT5yc3QpIHsKPiAtCQllcnIgPSByZXNldF9jb250cm9s X2Fzc2VydChzb3ItPnJzdCk7Cj4gLQkJaWYgKGVyciA8IDApIHsKPiAtCQkJZGV2X2VycihkZXYs ICJmYWlsZWQgdG8gYXNzZXJ0IHJlc2V0OiAlZFxuIiwgZXJyKTsKPiAtCQkJcmV0dXJuIGVycjsK PiAtCQl9Cj4gLQo+IC0JCXJlc2V0X2NvbnRyb2xfcmVsZWFzZShzb3ItPnJzdCk7Cj4gLQl9Cj4g LQo+IC0JdXNsZWVwX3JhbmdlKDEwMDAsIDIwMDApOwo+IC0KPiAtCWNsa19kaXNhYmxlX3VucHJl cGFyZShzb3ItPmNsayk7Cj4gLQo+IC0JcmV0dXJuIDA7Cj4gLX0KPiAtCj4gLXN0YXRpYyBpbnQg dGVncmFfc29yX3J1bnRpbWVfcmVzdW1lKHN0cnVjdCBkZXZpY2UgKmRldikKPiAtewo+IC0Jc3Ry dWN0IHRlZ3JhX3NvciAqc29yID0gZGV2X2dldF9kcnZkYXRhKGRldik7Cj4gLQlpbnQgZXJyOwo+ IC0KPiAtCWVyciA9IGNsa19wcmVwYXJlX2VuYWJsZShzb3ItPmNsayk7Cj4gLQlpZiAoZXJyIDwg MCkgewo+IC0JCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGVuYWJsZSBjbG9jazogJWRcbiIsIGVy cik7Cj4gLQkJcmV0dXJuIGVycjsKPiAtCX0KPiAtCj4gLQl1c2xlZXBfcmFuZ2UoMTAwMCwgMjAw MCk7Cj4gLQo+IC0JaWYgKHNvci0+cnN0KSB7Cj4gLQkJZXJyID0gcmVzZXRfY29udHJvbF9hY3F1 aXJlKHNvci0+cnN0KTsKPiAtCQlpZiAoZXJyIDwgMCkgewo+IC0JCQlkZXZfZXJyKGRldiwgImZh aWxlZCB0byBhY3F1aXJlIHJlc2V0OiAlZFxuIiwgZXJyKTsKPiAtCQkJY2xrX2Rpc2FibGVfdW5w cmVwYXJlKHNvci0+Y2xrKTsKPiAtCQkJcmV0dXJuIGVycjsKPiAtCQl9Cj4gLQo+IC0JCWVyciA9 IHJlc2V0X2NvbnRyb2xfZGVhc3NlcnQoc29yLT5yc3QpOwo+IC0JCWlmIChlcnIgPCAwKSB7Cj4g LQkJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGRlYXNzZXJ0IHJlc2V0OiAlZFxuIiwgZXJyKTsK PiAtCQkJcmVzZXRfY29udHJvbF9yZWxlYXNlKHNvci0+cnN0KTsKPiAtCQkJY2xrX2Rpc2FibGVf dW5wcmVwYXJlKHNvci0+Y2xrKTsKPiAtCQkJcmV0dXJuIGVycjsKPiAtCQl9Cj4gLQl9Cj4gLQo+ IC0JcmV0dXJuIDA7Cj4gLX0KPiAtCj4gICBzdGF0aWMgaW50IHRlZ3JhX3Nvcl9zdXNwZW5kKHN0 cnVjdCBkZXZpY2UgKmRldikKPiAgIHsKPiAgIAlzdHJ1Y3QgdGVncmFfc29yICpzb3IgPSBkZXZf Z2V0X2RydmRhdGEoZGV2KTsKPiBAQCAtMzk3NCw4ICszOTk3LDkgQEAgc3RhdGljIGludCB0ZWdy YV9zb3Jfc3VzcGVuZChzdHJ1Y3QgZGV2aWNlICpkZXYpCj4gICAKPiAgIAlpZiAoc29yLT5oZG1p X3N1cHBseSkgewo+ICAgCQllcnIgPSByZWd1bGF0b3JfZGlzYWJsZShzb3ItPmhkbWlfc3VwcGx5 KTsKPiAtCQlpZiAoZXJyIDwgMCkKPiArCQlpZiAoZXJyIDwgMCkgewo+ICAgCQkJcmV0dXJuIGVy cjsKPiArCQl9Cj4gICAJfQo+ICAgCj4gICAJcmV0dXJuIDA7Cj4gQEAgLTM5OTYsOCArNDAyMCw2 IEBAIHN0YXRpYyBpbnQgdGVncmFfc29yX3Jlc3VtZShzdHJ1Y3QgZGV2aWNlICpkZXYpCj4gICB9 Cj4gICAKPiAgIHN0YXRpYyBjb25zdCBzdHJ1Y3QgZGV2X3BtX29wcyB0ZWdyYV9zb3JfcG1fb3Bz ID0gewo+IC0JU0VUX1JVTlRJTUVfUE1fT1BTKHRlZ3JhX3Nvcl9ydW50aW1lX3N1c3BlbmQsIHRl Z3JhX3Nvcl9ydW50aW1lX3Jlc3VtZSwKPiAtCQkJICAgTlVMTCkKPiAgIAlTRVRfU1lTVEVNX1NM RUVQX1BNX09QUyh0ZWdyYV9zb3Jfc3VzcGVuZCwgdGVncmFfc29yX3Jlc3VtZSkKPiAgIH07Cj4g ICAKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL3ZpYy5jIGIvZHJpdmVycy9n cHUvZHJtL3RlZ3JhL3ZpYy5jCj4gaW5kZXggYWRlNTZiODYwY2Y5Li42Nzg5NjFhZGExN2YgMTAw NjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL3ZpYy5jCj4gKysrIGIvZHJpdmVycy9n cHUvZHJtL3RlZ3JhL3ZpYy5jCj4gQEAgLTUyLDQ4ICs1Miw2IEBAIHN0YXRpYyB2b2lkIHZpY193 cml0ZWwoc3RydWN0IHZpYyAqdmljLCB1MzIgdmFsdWUsIHVuc2lnbmVkIGludCBvZmZzZXQpCj4g ICAJd3JpdGVsKHZhbHVlLCB2aWMtPnJlZ3MgKyBvZmZzZXQpOwo+ICAgfQo+ICAgCj4gLXN0YXRp YyBpbnQgdmljX3J1bnRpbWVfcmVzdW1lKHN0cnVjdCBkZXZpY2UgKmRldikKPiAtewo+IC0Jc3Ry dWN0IHZpYyAqdmljID0gZGV2X2dldF9kcnZkYXRhKGRldik7Cj4gLQlpbnQgZXJyOwo+IC0KPiAt CWVyciA9IGNsa19wcmVwYXJlX2VuYWJsZSh2aWMtPmNsayk7Cj4gLQlpZiAoZXJyIDwgMCkKPiAt CQlyZXR1cm4gZXJyOwo+IC0KPiAtCXVzbGVlcF9yYW5nZSgxMCwgMjApOwo+IC0KPiAtCWVyciA9 IHJlc2V0X2NvbnRyb2xfZGVhc3NlcnQodmljLT5yc3QpOwo+IC0JaWYgKGVyciA8IDApCj4gLQkJ Z290byBkaXNhYmxlOwo+IC0KPiAtCXVzbGVlcF9yYW5nZSgxMCwgMjApOwo+IC0KPiAtCXJldHVy biAwOwo+IC0KPiAtZGlzYWJsZToKPiAtCWNsa19kaXNhYmxlX3VucHJlcGFyZSh2aWMtPmNsayk7 Cj4gLQlyZXR1cm4gZXJyOwo+IC19Cj4gLQo+IC1zdGF0aWMgaW50IHZpY19ydW50aW1lX3N1c3Bl bmQoc3RydWN0IGRldmljZSAqZGV2KQo+IC17Cj4gLQlzdHJ1Y3QgdmljICp2aWMgPSBkZXZfZ2V0 X2RydmRhdGEoZGV2KTsKPiAtCWludCBlcnI7Cj4gLQo+IC0JZXJyID0gcmVzZXRfY29udHJvbF9h c3NlcnQodmljLT5yc3QpOwo+IC0JaWYgKGVyciA8IDApCj4gLQkJcmV0dXJuIGVycjsKPiAtCj4g LQl1c2xlZXBfcmFuZ2UoMjAwMCwgNDAwMCk7Cj4gLQo+IC0JY2xrX2Rpc2FibGVfdW5wcmVwYXJl KHZpYy0+Y2xrKTsKPiAtCj4gLQl2aWMtPmJvb3RlZCA9IGZhbHNlOwo+IC0KPiAtCXJldHVybiAw Owo+IC19Cj4gLQo+ICAgc3RhdGljIGludCB2aWNfYm9vdChzdHJ1Y3QgdmljICp2aWMpCj4gICB7 Cj4gICAjaWZkZWYgQ09ORklHX0lPTU1VX0FQSQo+IEBAIC0yNDAsOSArMTk4LDYyIEBAIHN0YXRp YyBpbnQgdmljX2V4aXQoc3RydWN0IGhvc3QxeF9jbGllbnQgKmNsaWVudCkKPiAgIAlyZXR1cm4g MDsKPiAgIH0KPiAgIAo+ICtzdGF0aWMgaW50IHZpY19ydW50aW1lX3N1c3BlbmQoc3RydWN0IGhv c3QxeF9jbGllbnQgKmNsaWVudCkKPiArewo+ICsJc3RydWN0IHRlZ3JhX2RybV9jbGllbnQgKmRy bSA9IGhvc3QxeF90b19kcm1fY2xpZW50KGNsaWVudCk7Cj4gKwlzdHJ1Y3QgdmljICp2aWMgPSB0 b192aWMoZHJtKTsKPiArCWludCBlcnI7Cj4gKwo+ICsJZXJyID0gcmVzZXRfY29udHJvbF9hc3Nl cnQodmljLT5yc3QpOwo+ICsJaWYgKGVyciA8IDApCj4gKwkJcmV0dXJuIGVycjsKPiArCj4gKwl1 c2xlZXBfcmFuZ2UoMjAwMCwgNDAwMCk7Cj4gKwo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKHZp Yy0+Y2xrKTsKPiArCXBtX3J1bnRpbWVfcHV0X3N5bmModmljLT5kZXYpOwo+ICsKPiArCXZpYy0+ Ym9vdGVkID0gZmFsc2U7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQg dmljX3J1bnRpbWVfcmVzdW1lKHN0cnVjdCBob3N0MXhfY2xpZW50ICpjbGllbnQpCj4gK3sKPiAr CXN0cnVjdCB0ZWdyYV9kcm1fY2xpZW50ICpkcm0gPSBob3N0MXhfdG9fZHJtX2NsaWVudChjbGll bnQpOwo+ICsJc3RydWN0IHZpYyAqdmljID0gdG9fdmljKGRybSk7Cj4gKwlpbnQgZXJyOwo+ICsK PiArCWVyciA9IHBtX3J1bnRpbWVfZ2V0X3N5bmModmljLT5kZXYpOwo+ICsJaWYgKGVyciA8IDAp Cj4gKwkJcmV0dXJuIGVycjsKPiArCj4gKwllcnIgPSBjbGtfcHJlcGFyZV9lbmFibGUodmljLT5j bGspOwo+ICsJaWYgKGVyciA8IDApCj4gKwkJZ290byBwdXRfcnBtOwo+ICsKPiArCXVzbGVlcF9y YW5nZSgxMCwgMjApOwo+ICsKPiArCWVyciA9IHJlc2V0X2NvbnRyb2xfZGVhc3NlcnQodmljLT5y c3QpOwo+ICsJaWYgKGVyciA8IDApCj4gKwkJZ290byBkaXNhYmxlOwo+ICsKPiArCXVzbGVlcF9y YW5nZSgxMCwgMjApOwo+ICsKPiArCXJldHVybiAwOwo+ICsKPiArcHV0X3JwbToKPiArCXBtX3J1 bnRpbWVfcHV0X3N5bmModmljLT5kZXYpOwo+ICtkaXNhYmxlOgo+ICsJY2xrX2Rpc2FibGVfdW5w cmVwYXJlKHZpYy0+Y2xrKTsKPiArCXJldHVybiBlcnI7Cj4gK30KPiArCj4gICBzdGF0aWMgY29u c3Qgc3RydWN0IGhvc3QxeF9jbGllbnRfb3BzIHZpY19jbGllbnRfb3BzID0gewo+ICAgCS5pbml0 ID0gdmljX2luaXQsCj4gICAJLmV4aXQgPSB2aWNfZXhpdCwKPiArCS5zdXNwZW5kID0gdmljX3J1 bnRpbWVfc3VzcGVuZCwKPiArCS5yZXN1bWUgPSB2aWNfcnVudGltZV9yZXN1bWUsCj4gICB9Owo+ ICAgCj4gICBzdGF0aWMgaW50IHZpY19sb2FkX2Zpcm13YXJlKHN0cnVjdCB2aWMgKnZpYykKPiBA QCAtMzE0LDM4ICszMjUsMzcgQEAgc3RhdGljIGludCB2aWNfb3Blbl9jaGFubmVsKHN0cnVjdCB0 ZWdyYV9kcm1fY2xpZW50ICpjbGllbnQsCj4gICAJc3RydWN0IHZpYyAqdmljID0gdG9fdmljKGNs aWVudCk7Cj4gICAJaW50IGVycjsKPiAgIAo+IC0JZXJyID0gcG1fcnVudGltZV9nZXRfc3luYyh2 aWMtPmRldik7Cj4gKwllcnIgPSBob3N0MXhfY2xpZW50X3Jlc3VtZSgmY2xpZW50LT5iYXNlKTsK PiAgIAlpZiAoZXJyIDwgMCkKPiAgIAkJcmV0dXJuIGVycjsKPiAgIAo+ICAgCWVyciA9IHZpY19s b2FkX2Zpcm13YXJlKHZpYyk7Cj4gICAJaWYgKGVyciA8IDApCj4gLQkJZ290byBycG1fcHV0Owo+ ICsJCWdvdG8gc3VzcGVuZDsKPiAgIAo+ICAgCWVyciA9IHZpY19ib290KHZpYyk7Cj4gICAJaWYg KGVyciA8IDApCj4gLQkJZ290byBycG1fcHV0Owo+ICsJCWdvdG8gc3VzcGVuZDsKPiAgIAo+ICAg CWNvbnRleHQtPmNoYW5uZWwgPSBob3N0MXhfY2hhbm5lbF9nZXQodmljLT5jaGFubmVsKTsKPiAg IAlpZiAoIWNvbnRleHQtPmNoYW5uZWwpIHsKPiAgIAkJZXJyID0gLUVOT01FTTsKPiAtCQlnb3Rv IHJwbV9wdXQ7Cj4gKwkJZ290byBzdXNwZW5kOwo+ICAgCX0KPiAgIAo+ICAgCXJldHVybiAwOwo+ ICAgCj4gLXJwbV9wdXQ6Cj4gLQlwbV9ydW50aW1lX3B1dCh2aWMtPmRldik7Cj4gK3N1c3BlbmQ6 Cj4gKwlob3N0MXhfY2xpZW50X3N1c3BlbmQoJmNsaWVudC0+YmFzZSk7Cj4gICAJcmV0dXJuIGVy cjsKPiAgIH0KPiAgIAo+ICAgc3RhdGljIHZvaWQgdmljX2Nsb3NlX2NoYW5uZWwoc3RydWN0IHRl Z3JhX2RybV9jb250ZXh0ICpjb250ZXh0KQo+ICAgewo+IC0Jc3RydWN0IHZpYyAqdmljID0gdG9f dmljKGNvbnRleHQtPmNsaWVudCk7Cj4gKwlzdHJ1Y3QgaG9zdDF4X2NsaWVudCAqY2xpZW50ID0g JmNvbnRleHQtPmNsaWVudC0+YmFzZTsKPiAgIAo+ICAgCWhvc3QxeF9jaGFubmVsX3B1dChjb250 ZXh0LT5jaGFubmVsKTsKPiAtCj4gLQlwbV9ydW50aW1lX3B1dCh2aWMtPmRldik7Cj4gKwlob3N0 MXhfY2xpZW50X3N1c3BlbmQoY2xpZW50KTsKPiAgIH0KPiAgIAo+ICAgc3RhdGljIGNvbnN0IHN0 cnVjdCB0ZWdyYV9kcm1fY2xpZW50X29wcyB2aWNfb3BzID0gewo+IEBAIC00NzIsMTYgKzQ4Miw5 IEBAIHN0YXRpYyBpbnQgdmljX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4g ICAJfQo+ICAgCj4gICAJcG1fcnVudGltZV9lbmFibGUoJnBkZXYtPmRldik7Cj4gLQlpZiAoIXBt X3J1bnRpbWVfZW5hYmxlZCgmcGRldi0+ZGV2KSkgewo+IC0JCWVyciA9IHZpY19ydW50aW1lX3Jl c3VtZSgmcGRldi0+ZGV2KTsKPiAtCQlpZiAoZXJyIDwgMCkKPiAtCQkJZ290byB1bnJlZ2lzdGVy X2NsaWVudDsKPiAtCX0KPiAgIAo+ICAgCXJldHVybiAwOwo+ICAgCj4gLXVucmVnaXN0ZXJfY2xp ZW50Ogo+IC0JaG9zdDF4X2NsaWVudF91bnJlZ2lzdGVyKCZ2aWMtPmNsaWVudC5iYXNlKTsKPiAg IGV4aXRfZmFsY29uOgo+ICAgCWZhbGNvbl9leGl0KCZ2aWMtPmZhbGNvbik7Cj4gICAKPiBAQCAt NDkzLDYgKzQ5Niw4IEBAIHN0YXRpYyBpbnQgdmljX3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2 aWNlICpwZGV2KQo+ICAgCXN0cnVjdCB2aWMgKnZpYyA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHBk ZXYpOwo+ICAgCWludCBlcnI7Cj4gICAKPiArCXBtX3J1bnRpbWVfZGlzYWJsZSgmcGRldi0+ZGV2 KTsKPiArCj4gICAJZXJyID0gaG9zdDF4X2NsaWVudF91bnJlZ2lzdGVyKCZ2aWMtPmNsaWVudC5i YXNlKTsKPiAgIAlpZiAoZXJyIDwgMCkgewo+ICAgCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJmYWls ZWQgdG8gdW5yZWdpc3RlciBob3N0MXggY2xpZW50OiAlZFxuIiwKPiBAQCAtNTAwLDI1ICs1MDUs MTUgQEAgc3RhdGljIGludCB2aWNfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYp Cj4gICAJCXJldHVybiBlcnI7Cj4gICAJfQo+ICAgCj4gLQlpZiAocG1fcnVudGltZV9lbmFibGVk KCZwZGV2LT5kZXYpKQo+IC0JCXBtX3J1bnRpbWVfZGlzYWJsZSgmcGRldi0+ZGV2KTsKPiAtCWVs c2UKPiAtCQl2aWNfcnVudGltZV9zdXNwZW5kKCZwZGV2LT5kZXYpOwo+IC0KPiAgIAlmYWxjb25f ZXhpdCgmdmljLT5mYWxjb24pOwo+ICAgCj4gICAJcmV0dXJuIDA7Cj4gICB9Cj4gICAKPiAtc3Rh dGljIGNvbnN0IHN0cnVjdCBkZXZfcG1fb3BzIHZpY19wbV9vcHMgPSB7Cj4gLQlTRVRfUlVOVElN RV9QTV9PUFModmljX3J1bnRpbWVfc3VzcGVuZCwgdmljX3J1bnRpbWVfcmVzdW1lLCBOVUxMKQo+ IC19Owo+IC0KPiAgIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgdGVncmFfdmljX2RyaXZlciA9IHsK PiAgIAkuZHJpdmVyID0gewo+ICAgCQkubmFtZSA9ICJ0ZWdyYS12aWMiLAo+ICAgCQkub2ZfbWF0 Y2hfdGFibGUgPSB0ZWdyYV92aWNfb2ZfbWF0Y2gsCj4gLQkJLnBtID0gJnZpY19wbV9vcHMKPiAg IAl9LAo+ICAgCS5wcm9iZSA9IHZpY19wcm9iZSwKPiAgIAkucmVtb3ZlID0gdmljX3JlbW92ZSwK PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvaG9zdDF4L2J1cy5jIGIvZHJpdmVycy9ncHUvaG9z dDF4L2J1cy5jCj4gaW5kZXggNTBkNTAwMzQ1ZDA0Li42YTk5NWRiNTFkNmQgMTAwNjQ0Cj4gLS0t IGEvZHJpdmVycy9ncHUvaG9zdDF4L2J1cy5jCj4gKysrIGIvZHJpdmVycy9ncHUvaG9zdDF4L2J1 cy5jCj4gQEAgLTcxMCw2ICs3MTAsMTAgQEAgaW50IGhvc3QxeF9jbGllbnRfcmVnaXN0ZXIoc3Ry dWN0IGhvc3QxeF9jbGllbnQgKmNsaWVudCkKPiAgIAlzdHJ1Y3QgaG9zdDF4ICpob3N0MXg7Cj4g ICAJaW50IGVycjsKPiAgIAo+ICsJSU5JVF9MSVNUX0hFQUQoJmNsaWVudC0+bGlzdCk7Cj4gKwlt dXRleF9pbml0KCZjbGllbnQtPmxvY2spOwo+ICsJY2xpZW50LT51c2Vjb3VudCA9IDA7Cj4gKwo+ ICAgCW11dGV4X2xvY2soJmRldmljZXNfbG9jayk7Cj4gICAKPiAgIAlsaXN0X2Zvcl9lYWNoX2Vu dHJ5KGhvc3QxeCwgJmRldmljZXMsIGxpc3QpIHsKPiBAQCAtNzY4LDMgKzc3Miw3NCBAQCBpbnQg aG9zdDF4X2NsaWVudF91bnJlZ2lzdGVyKHN0cnVjdCBob3N0MXhfY2xpZW50ICpjbGllbnQpCj4g ICAJcmV0dXJuIDA7Cj4gICB9Cj4gICBFWFBPUlRfU1lNQk9MKGhvc3QxeF9jbGllbnRfdW5yZWdp c3Rlcik7Cj4gKwo+ICtpbnQgaG9zdDF4X2NsaWVudF9zdXNwZW5kKHN0cnVjdCBob3N0MXhfY2xp ZW50ICpjbGllbnQpCj4gK3sKPiArCWludCBlcnIgPSAwOwo+ICsKPiArCW11dGV4X2xvY2soJmNs aWVudC0+bG9jayk7Cj4gKwo+ICsJaWYgKGNsaWVudC0+dXNlY291bnQgPT0gMSkgewo+ICsJCWlm IChjbGllbnQtPm9wcyAmJiBjbGllbnQtPm9wcy0+c3VzcGVuZCkgewo+ICsJCQllcnIgPSBjbGll bnQtPm9wcy0+c3VzcGVuZChjbGllbnQpOwo+ICsJCQlpZiAoZXJyIDwgMCkKPiArCQkJCWdvdG8g dW5sb2NrOwo+ICsJCX0KPiArCX0KPiArCj4gKwljbGllbnQtPnVzZWNvdW50LS07Cj4gKwlkZXZf ZGJnKGNsaWVudC0+ZGV2LCAidXNlIGNvdW50OiAldVxuIiwgY2xpZW50LT51c2Vjb3VudCk7Cj4g Kwo+ICsJaWYgKGNsaWVudC0+cGFyZW50KSB7Cj4gKwkJZXJyID0gaG9zdDF4X2NsaWVudF9zdXNw ZW5kKGNsaWVudC0+cGFyZW50KTsKPiArCQlpZiAoZXJyIDwgMCkKPiArCQkJZ290byByZXN1bWU7 Cj4gKwl9Cj4gKwo+ICsJZ290byB1bmxvY2s7Cj4gKwo+ICtyZXN1bWU6Cj4gKwlpZiAoY2xpZW50 LT51c2Vjb3VudCA9PSAwKQo+ICsJCWlmIChjbGllbnQtPm9wcyAmJiBjbGllbnQtPm9wcy0+cmVz dW1lKQo+ICsJCQljbGllbnQtPm9wcy0+cmVzdW1lKGNsaWVudCk7Cj4gKwo+ICsJY2xpZW50LT51 c2Vjb3VudCsrOwo+ICt1bmxvY2s6Cj4gKwltdXRleF91bmxvY2soJmNsaWVudC0+bG9jayk7Cj4g KwlyZXR1cm4gZXJyOwo+ICt9Cj4gK0VYUE9SVF9TWU1CT0woaG9zdDF4X2NsaWVudF9zdXNwZW5k KTsKPiArCj4gK2ludCBob3N0MXhfY2xpZW50X3Jlc3VtZShzdHJ1Y3QgaG9zdDF4X2NsaWVudCAq Y2xpZW50KQo+ICt7Cj4gKwlpbnQgZXJyID0gMDsKPiArCj4gKwltdXRleF9sb2NrKCZjbGllbnQt PmxvY2spOwo+ICsKPiArCWlmIChjbGllbnQtPnBhcmVudCkgewo+ICsJCWVyciA9IGhvc3QxeF9j bGllbnRfcmVzdW1lKGNsaWVudC0+cGFyZW50KTsKPiArCQlpZiAoZXJyIDwgMCkKPiArCQkJZ290 byB1bmxvY2s7Cj4gKwl9Cj4gKwo+ICsJaWYgKGNsaWVudC0+dXNlY291bnQgPT0gMCkgewo+ICsJ CWlmIChjbGllbnQtPm9wcyAmJiBjbGllbnQtPm9wcy0+cmVzdW1lKSB7Cj4gKwkJCWVyciA9IGNs aWVudC0+b3BzLT5yZXN1bWUoY2xpZW50KTsKPiArCQkJaWYgKGVyciA8IDApCj4gKwkJCQlnb3Rv IHN1c3BlbmQ7Cj4gKwkJfQo+ICsJfQo+ICsKPiArCWNsaWVudC0+dXNlY291bnQrKzsKPiArCWRl dl9kYmcoY2xpZW50LT5kZXYsICJ1c2UgY291bnQ6ICV1XG4iLCBjbGllbnQtPnVzZWNvdW50KTsK PiArCj4gKwlnb3RvIHVubG9jazsKPiArCj4gK3N1c3BlbmQ6Cj4gKwlpZiAoY2xpZW50LT5wYXJl bnQpCj4gKwkJaG9zdDF4X2NsaWVudF9zdXNwZW5kKGNsaWVudC0+cGFyZW50KTsKPiArdW5sb2Nr Ogo+ICsJbXV0ZXhfdW5sb2NrKCZjbGllbnQtPmxvY2spOwo+ICsJcmV0dXJuIGVycjsKPiArfQo+ ICtFWFBPUlRfU1lNQk9MKGhvc3QxeF9jbGllbnRfcmVzdW1lKTsKPiBkaWZmIC0tZ2l0IGEvaW5j bHVkZS9saW51eC9ob3N0MXguaCBiL2luY2x1ZGUvbGludXgvaG9zdDF4LmgKPiBpbmRleCA0NzBh MTkzYTlmZWQuLjAyNTRlYmNkYzBhNyAxMDA2NDQKPiAtLS0gYS9pbmNsdWRlL2xpbnV4L2hvc3Qx eC5oCj4gKysrIGIvaW5jbHVkZS9saW51eC9ob3N0MXguaAo+IEBAIC0yNCwxMCArMjQsMTQgQEAg c3RydWN0IGlvbW11X2dyb3VwOwo+ICAgICogc3RydWN0IGhvc3QxeF9jbGllbnRfb3BzIC0gaG9z dDF4IGNsaWVudCBvcGVyYXRpb25zCj4gICAgKiBAaW5pdDogaG9zdDF4IGNsaWVudCBpbml0aWFs aXphdGlvbiBjb2RlCj4gICAgKiBAZXhpdDogaG9zdDF4IGNsaWVudCB0ZWFyIGRvd24gY29kZQo+ ICsgKiBAc3VzcGVuZDogaG9zdDF4IGNsaWVudCBzdXNwZW5kIGNvZGUKPiArICogQHJlc3VtZTog aG9zdDF4IGNsaWVudCByZXN1bWUgY29kZQo+ICAgICovCj4gICBzdHJ1Y3QgaG9zdDF4X2NsaWVu dF9vcHMgewo+ICAgCWludCAoKmluaXQpKHN0cnVjdCBob3N0MXhfY2xpZW50ICpjbGllbnQpOwo+ ICAgCWludCAoKmV4aXQpKHN0cnVjdCBob3N0MXhfY2xpZW50ICpjbGllbnQpOwo+ICsJaW50ICgq c3VzcGVuZCkoc3RydWN0IGhvc3QxeF9jbGllbnQgKmNsaWVudCk7Cj4gKwlpbnQgKCpyZXN1bWUp KHN0cnVjdCBob3N0MXhfY2xpZW50ICpjbGllbnQpOwo+ICAgfTsKPiAgIAo+ICAgLyoqCj4gQEAg LTU1LDYgKzU5LDEwIEBAIHN0cnVjdCBob3N0MXhfY2xpZW50IHsKPiAgIAo+ICAgCXN0cnVjdCBo b3N0MXhfc3luY3B0ICoqc3luY3B0czsKPiAgIAl1bnNpZ25lZCBpbnQgbnVtX3N5bmNwdHM7Cj4g Kwo+ICsJc3RydWN0IGhvc3QxeF9jbGllbnQgKnBhcmVudDsKPiArCXVuc2lnbmVkIGludCB1c2Vj b3VudDsKPiArCXN0cnVjdCBtdXRleCBsb2NrOwo+ICAgfTsKPiAgIAo+ICAgLyoKPiBAQCAtMzA5 LDYgKzMxNyw5IEBAIGludCBob3N0MXhfZGV2aWNlX2V4aXQoc3RydWN0IGhvc3QxeF9kZXZpY2Ug KmRldmljZSk7Cj4gICBpbnQgaG9zdDF4X2NsaWVudF9yZWdpc3RlcihzdHJ1Y3QgaG9zdDF4X2Ns aWVudCAqY2xpZW50KTsKPiAgIGludCBob3N0MXhfY2xpZW50X3VucmVnaXN0ZXIoc3RydWN0IGhv c3QxeF9jbGllbnQgKmNsaWVudCk7Cj4gICAKPiAraW50IGhvc3QxeF9jbGllbnRfc3VzcGVuZChz dHJ1Y3QgaG9zdDF4X2NsaWVudCAqY2xpZW50KTsKPiAraW50IGhvc3QxeF9jbGllbnRfcmVzdW1l KHN0cnVjdCBob3N0MXhfY2xpZW50ICpjbGllbnQpOwo+ICsKPiAgIHN0cnVjdCB0ZWdyYV9taXBp X2RldmljZTsKPiAgIAo+ICAgc3RydWN0IHRlZ3JhX21pcGlfZGV2aWNlICp0ZWdyYV9taXBpX3Jl cXVlc3Qoc3RydWN0IGRldmljZSAqZGV2aWNlKTsKPiAKX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX18KZHJpLWRldmVsIG1haWxpbmcgbGlzdApkcmktZGV2ZWxA bGlzdHMuZnJlZWRlc2t0b3Aub3JnCmh0dHBzOi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxt YW4vbGlzdGluZm8vZHJpLWRldmVs From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.1 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8CA4AC43603 for ; Wed, 4 Dec 2019 08:37:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 313D5206DF for ; Wed, 4 Dec 2019 08:37:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=kapsi.fi header.i=@kapsi.fi header.b="X13POG+a" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726217AbfLDIhP (ORCPT ); Wed, 4 Dec 2019 03:37:15 -0500 Received: from mail.kapsi.fi ([91.232.154.25]:56331 "EHLO mail.kapsi.fi" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725839AbfLDIhP (ORCPT ); Wed, 4 Dec 2019 03:37:15 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=kapsi.fi; s=20161220; h=Content-Transfer-Encoding:Content-Type:In-Reply-To: MIME-Version:Date:Message-ID:From:References:Cc:To:Subject:Sender:Reply-To: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=4Wo8CDiGqRu42KzdF1MFCIgm+For51VuH6dDjPoGGK8=; b=X13POG+adQTZYlI5b409ssJ+b5 s/Cs+CLrGxO/8Nq1qYJm63gG6jAOG804XVem9MLKl3wcy/wyPwpqsPjw8sVlE6kS9/owD8vdEPyC9 5il0uKbJErLBPy8ilE8w0fAA+jFRpIfLJkNsI7ly7xcKBTeIaxZ4GGEKkRG/IcFjRVAr91DfccwH3 MrqcG6eykRmS57FprZy4MHd1G6/cyRx1/SWpmYqGH/2M/oGac+2pOQdp3CTnNt6OtYsGN4j13p6iL D0DjvhAuQOoFTZM2YEWOyrWPqNwybtZDhrjkdWB2qvGDKunsW4D1gAH+Fsr1E/K3e0AJPUo4AO/78 vuzR9kaw==; Received: from [193.209.96.43] (helo=[10.21.26.179]) by mail.kapsi.fi with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.89) (envelope-from ) id 1icQ9l-00051F-GS; Wed, 04 Dec 2019 10:37:09 +0200 Subject: Re: [PATCH 2/2] drm/tegra: Do not implement runtime PM To: Thierry Reding Cc: linux-tegra@vger.kernel.org, "Rafael J. Wysocki" , dri-devel@lists.freedesktop.org, linux-pm@vger.kernel.org References: <20191203162733.1436800-1-thierry.reding@gmail.com> <20191203162733.1436800-2-thierry.reding@gmail.com> From: Mikko Perttunen Message-ID: <61acda7c-f5c8-e7f6-0e34-c25bec489cdc@kapsi.fi> Date: Wed, 4 Dec 2019 10:37:04 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.2.1 MIME-Version: 1.0 In-Reply-To: <20191203162733.1436800-2-thierry.reding@gmail.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-SA-Exim-Connect-IP: 193.209.96.43 X-SA-Exim-Mail-From: cyndis@kapsi.fi X-SA-Exim-Scanned: No (on mail.kapsi.fi); SAEximRunCond expanded to false Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Is there any specific reason non-display engines like VIC cannot continue to use runtime PM? I know being able to do 'echo on > power/control' for VIC has been quite useful for debugging in the past. Mikko On 3.12.2019 18.27, Thierry Reding wrote: > From: Thierry Reding > > The Tegra DRM driver heavily relies on the implementations for runtime > suspend/resume to be called at specific times. Unfortunately, there are > some cases where that doesn't work. One example is if the user disables > runtime PM for a given subdevice. Another example is that the PM core > acquires a reference to runtime PM during system sleep, effectively > preventing devices from going into low power modes. This is intentional > to avoid nasty race conditions, but it also causes system sleep to not > function properly on all Tegra systems. > > Fix this by not implementing runtime PM at all. Instead, a minimal, > reference-counted suspend/resume infrastructure is added to the host1x > bus. This has the benefit that it can be used regardless of the system > power state (or any transitions we might be in), or whether or not the > user allows runtime PM. > > Atomic modesetting guarantees that these functions will end up being > called at the right point in time, so the pitfalls for the more generic > runtime PM do not apply here. > > Signed-off-by: Thierry Reding > --- > drivers/gpu/drm/tegra/dc.c | 141 ++++++++++++++---------- > drivers/gpu/drm/tegra/dpaux.c | 2 +- > drivers/gpu/drm/tegra/drm.h | 2 + > drivers/gpu/drm/tegra/dsi.c | 175 ++++++++++++++++-------------- > drivers/gpu/drm/tegra/hdmi.c | 116 +++++++++++--------- > drivers/gpu/drm/tegra/hub.c | 194 ++++++++++++++++++++-------------- > drivers/gpu/drm/tegra/hub.h | 2 +- > drivers/gpu/drm/tegra/sor.c | 154 +++++++++++++++------------ > drivers/gpu/drm/tegra/vic.c | 131 +++++++++++------------ > drivers/gpu/host1x/bus.c | 75 +++++++++++++ > include/linux/host1x.h | 11 ++ > 11 files changed, 604 insertions(+), 399 deletions(-) > > diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c > index 2983eb33f2be..871046f3f469 100644 > --- a/drivers/gpu/drm/tegra/dc.c > +++ b/drivers/gpu/drm/tegra/dc.c > @@ -1737,6 +1737,7 @@ static void tegra_crtc_atomic_disable(struct drm_crtc *crtc, > { > struct tegra_dc *dc = to_tegra_dc(crtc); > u32 value; > + int err; > > if (!tegra_dc_idle(dc)) { > tegra_dc_stop(dc); > @@ -1783,7 +1784,9 @@ static void tegra_crtc_atomic_disable(struct drm_crtc *crtc, > > spin_unlock_irq(&crtc->dev->event_lock); > > - pm_runtime_put_sync(dc->dev); > + err = host1x_client_suspend(&dc->client); > + if (err < 0) > + dev_err(dc->dev, "failed to suspend: %d\n", err); > } > > static void tegra_crtc_atomic_enable(struct drm_crtc *crtc, > @@ -1793,8 +1796,13 @@ static void tegra_crtc_atomic_enable(struct drm_crtc *crtc, > struct tegra_dc_state *state = to_dc_state(crtc->state); > struct tegra_dc *dc = to_tegra_dc(crtc); > u32 value; > + int err; > > - pm_runtime_get_sync(dc->dev); > + err = host1x_client_resume(&dc->client); > + if (err < 0) { > + dev_err(dc->dev, "failed to resume: %d\n", err); > + return; > + } > > /* initialize display controller */ > if (dc->syncpt) { > @@ -2022,6 +2030,15 @@ static int tegra_dc_init(struct host1x_client *client) > if (!tegra_dc_has_window_groups(dc)) > return 0; > > + /* > + * Set the display hub as the host1x client parent for the display > + * controller. This is needed for the runtime reference counting that > + * ensures the display hub is always powered when any of the display > + * controllers are. > + */ > + if (dc->soc->has_nvdisplay) > + client->parent = &tegra->hub->client; > + > dc->syncpt = host1x_syncpt_request(client, flags); > if (!dc->syncpt) > dev_warn(dc->dev, "failed to allocate syncpoint\n"); > @@ -2131,9 +2148,74 @@ static int tegra_dc_exit(struct host1x_client *client) > return 0; > } > > +static int tegra_dc_runtime_suspend(struct host1x_client *client) > +{ > + struct tegra_dc *dc = host1x_client_to_dc(client); > + struct device *dev = client->dev; > + int err; > + > + err = reset_control_assert(dc->rst); > + if (err < 0) { > + dev_err(dev, "failed to assert reset: %d\n", err); > + return err; > + } > + > + if (dc->soc->has_powergate) > + tegra_powergate_power_off(dc->powergate); > + > + clk_disable_unprepare(dc->clk); > + pm_runtime_put_sync(dev); > + > + return 0; > +} > + > +static int tegra_dc_runtime_resume(struct host1x_client *client) > +{ > + struct tegra_dc *dc = host1x_client_to_dc(client); > + struct device *dev = client->dev; > + int err; > + > + err = pm_runtime_get_sync(dev); > + if (err < 0) { > + dev_err(dev, "failed to get runtime PM: %d\n", err); > + return err; > + } > + > + if (dc->soc->has_powergate) { > + err = tegra_powergate_sequence_power_up(dc->powergate, dc->clk, > + dc->rst); > + if (err < 0) { > + dev_err(dev, "failed to power partition: %d\n", err); > + goto put_rpm; > + } > + } else { > + err = clk_prepare_enable(dc->clk); > + if (err < 0) { > + dev_err(dev, "failed to enable clock: %d\n", err); > + goto put_rpm; > + } > + > + err = reset_control_deassert(dc->rst); > + if (err < 0) { > + dev_err(dev, "failed to deassert reset: %d\n", err); > + goto disable_clk; > + } > + } > + > + return 0; > + > +disable_clk: > + clk_disable_unprepare(dc->clk); > +put_rpm: > + pm_runtime_put_sync(dev); > + return err; > +} > + > static const struct host1x_client_ops dc_client_ops = { > .init = tegra_dc_init, > .exit = tegra_dc_exit, > + .suspend = tegra_dc_runtime_suspend, > + .resume = tegra_dc_runtime_resume, > }; > > static const struct tegra_dc_soc_info tegra20_dc_soc_info = { > @@ -2545,65 +2627,10 @@ static int tegra_dc_remove(struct platform_device *pdev) > return 0; > } > > -#ifdef CONFIG_PM > -static int tegra_dc_suspend(struct device *dev) > -{ > - struct tegra_dc *dc = dev_get_drvdata(dev); > - int err; > - > - err = reset_control_assert(dc->rst); > - if (err < 0) { > - dev_err(dev, "failed to assert reset: %d\n", err); > - return err; > - } > - > - if (dc->soc->has_powergate) > - tegra_powergate_power_off(dc->powergate); > - > - clk_disable_unprepare(dc->clk); > - > - return 0; > -} > - > -static int tegra_dc_resume(struct device *dev) > -{ > - struct tegra_dc *dc = dev_get_drvdata(dev); > - int err; > - > - if (dc->soc->has_powergate) { > - err = tegra_powergate_sequence_power_up(dc->powergate, dc->clk, > - dc->rst); > - if (err < 0) { > - dev_err(dev, "failed to power partition: %d\n", err); > - return err; > - } > - } else { > - err = clk_prepare_enable(dc->clk); > - if (err < 0) { > - dev_err(dev, "failed to enable clock: %d\n", err); > - return err; > - } > - > - err = reset_control_deassert(dc->rst); > - if (err < 0) { > - dev_err(dev, "failed to deassert reset: %d\n", err); > - return err; > - } > - } > - > - return 0; > -} > -#endif > - > -static const struct dev_pm_ops tegra_dc_pm_ops = { > - SET_RUNTIME_PM_OPS(tegra_dc_suspend, tegra_dc_resume, NULL) > -}; > - > struct platform_driver tegra_dc_driver = { > .driver = { > .name = "tegra-dc", > .of_match_table = tegra_dc_of_match, > - .pm = &tegra_dc_pm_ops, > }, > .probe = tegra_dc_probe, > .remove = tegra_dc_remove, > diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c > index 622cdf1ad246..7dfb50f65067 100644 > --- a/drivers/gpu/drm/tegra/dpaux.c > +++ b/drivers/gpu/drm/tegra/dpaux.c > @@ -588,7 +588,7 @@ static int tegra_dpaux_remove(struct platform_device *pdev) > /* make sure pads are powered down when not in use */ > tegra_dpaux_pad_power_down(dpaux); > > - pm_runtime_put(&pdev->dev); > + pm_runtime_put_sync(&pdev->dev); > pm_runtime_disable(&pdev->dev); > > drm_dp_aux_unregister(&dpaux->aux); > diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h > index d941553f7a3d..ed99b67deb29 100644 > --- a/drivers/gpu/drm/tegra/drm.h > +++ b/drivers/gpu/drm/tegra/drm.h > @@ -144,6 +144,8 @@ int tegra_output_init(struct drm_device *drm, struct tegra_output *output); > void tegra_output_exit(struct tegra_output *output); > void tegra_output_find_possible_crtcs(struct tegra_output *output, > struct drm_device *drm); > +int tegra_output_suspend(struct tegra_output *output); > +int tegra_output_resume(struct tegra_output *output); > > int tegra_output_connector_get_modes(struct drm_connector *connector); > enum drm_connector_status > diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c > index ec475d022fa0..88b9d64c77bf 100644 > --- a/drivers/gpu/drm/tegra/dsi.c > +++ b/drivers/gpu/drm/tegra/dsi.c > @@ -840,7 +840,9 @@ static void tegra_dsi_unprepare(struct tegra_dsi *dsi) > dev_err(dsi->dev, "failed to disable MIPI calibration: %d\n", > err); > > - pm_runtime_put(dsi->dev); > + err = host1x_client_suspend(&dsi->client); > + if (err < 0) > + dev_err(dsi->dev, "failed to suspend: %d\n", err); > } > > static void tegra_dsi_encoder_disable(struct drm_encoder *encoder) > @@ -882,11 +884,15 @@ static void tegra_dsi_encoder_disable(struct drm_encoder *encoder) > tegra_dsi_unprepare(dsi); > } > > -static void tegra_dsi_prepare(struct tegra_dsi *dsi) > +static int tegra_dsi_prepare(struct tegra_dsi *dsi) > { > int err; > > - pm_runtime_get_sync(dsi->dev); > + err = host1x_client_resume(&dsi->client); > + if (err < 0) { > + dev_err(dsi->dev, "failed to resume: %d\n", err); > + return err; > + } > > err = tegra_mipi_enable(dsi->mipi); > if (err < 0) > @@ -899,6 +905,8 @@ static void tegra_dsi_prepare(struct tegra_dsi *dsi) > > if (dsi->slave) > tegra_dsi_prepare(dsi->slave); > + > + return 0; > } > > static void tegra_dsi_encoder_enable(struct drm_encoder *encoder) > @@ -909,8 +917,13 @@ static void tegra_dsi_encoder_enable(struct drm_encoder *encoder) > struct tegra_dsi *dsi = to_dsi(output); > struct tegra_dsi_state *state; > u32 value; > + int err; > > - tegra_dsi_prepare(dsi); > + err = tegra_dsi_prepare(dsi); > + if (err < 0) { > + dev_err(dsi->dev, "failed to prepare: %d\n", err); > + return; > + } > > state = tegra_dsi_get_state(dsi); > > @@ -1075,9 +1088,89 @@ static int tegra_dsi_exit(struct host1x_client *client) > return 0; > } > > +static int tegra_dsi_runtime_suspend(struct host1x_client *client) > +{ > + struct tegra_dsi *dsi = host1x_client_to_dsi(client); > + struct device *dev = client->dev; > + int err; > + > + if (dsi->rst) { > + err = reset_control_assert(dsi->rst); > + if (err < 0) { > + dev_err(dev, "failed to assert reset: %d\n", err); > + return err; > + } > + } > + > + usleep_range(1000, 2000); > + > + clk_disable_unprepare(dsi->clk_lp); > + clk_disable_unprepare(dsi->clk); > + > + regulator_disable(dsi->vdd); > + pm_runtime_put_sync(dev); > + > + return 0; > +} > + > +static int tegra_dsi_runtime_resume(struct host1x_client *client) > +{ > + struct tegra_dsi *dsi = host1x_client_to_dsi(client); > + struct device *dev = client->dev; > + int err; > + > + err = pm_runtime_get_sync(dev); > + if (err < 0) { > + dev_err(dev, "failed to get runtime PM: %d\n", err); > + return err; > + } > + > + err = regulator_enable(dsi->vdd); > + if (err < 0) { > + dev_err(dev, "failed to enable VDD supply: %d\n", err); > + goto put_rpm; > + } > + > + err = clk_prepare_enable(dsi->clk); > + if (err < 0) { > + dev_err(dev, "cannot enable DSI clock: %d\n", err); > + goto disable_vdd; > + } > + > + err = clk_prepare_enable(dsi->clk_lp); > + if (err < 0) { > + dev_err(dev, "cannot enable low-power clock: %d\n", err); > + goto disable_clk; > + } > + > + usleep_range(1000, 2000); > + > + if (dsi->rst) { > + err = reset_control_deassert(dsi->rst); > + if (err < 0) { > + dev_err(dev, "cannot assert reset: %d\n", err); > + goto disable_clk_lp; > + } > + } > + > + return 0; > + > +disable_clk_lp: > + clk_disable_unprepare(dsi->clk_lp); > +disable_clk: > + clk_disable_unprepare(dsi->clk); > +disable_vdd: > + regulator_disable(dsi->vdd); > +put_rpm: > + pm_runtime_put_sync(dev); > + return err; > +} > + > static const struct host1x_client_ops dsi_client_ops = { > .init = tegra_dsi_init, > .exit = tegra_dsi_exit, > + .suspend = tegra_dsi_runtime_suspend, > + .resume = tegra_dsi_runtime_resume, > }; > > static int tegra_dsi_setup_clocks(struct tegra_dsi *dsi) > @@ -1596,79 +1689,6 @@ static int tegra_dsi_remove(struct platform_device *pdev) > return 0; > } > > -#ifdef CONFIG_PM > -static int tegra_dsi_suspend(struct device *dev) > -{ > - struct tegra_dsi *dsi = dev_get_drvdata(dev); > - int err; > - > - if (dsi->rst) { > - err = reset_control_assert(dsi->rst); > - if (err < 0) { > - dev_err(dev, "failed to assert reset: %d\n", err); > - return err; > - } > - } > - > - usleep_range(1000, 2000); > - > - clk_disable_unprepare(dsi->clk_lp); > - clk_disable_unprepare(dsi->clk); > - > - regulator_disable(dsi->vdd); > - > - return 0; > -} > - > -static int tegra_dsi_resume(struct device *dev) > -{ > - struct tegra_dsi *dsi = dev_get_drvdata(dev); > - int err; > - > - err = regulator_enable(dsi->vdd); > - if (err < 0) { > - dev_err(dsi->dev, "failed to enable VDD supply: %d\n", err); > - return err; > - } > - > - err = clk_prepare_enable(dsi->clk); > - if (err < 0) { > - dev_err(dev, "cannot enable DSI clock: %d\n", err); > - goto disable_vdd; > - } > - > - err = clk_prepare_enable(dsi->clk_lp); > - if (err < 0) { > - dev_err(dev, "cannot enable low-power clock: %d\n", err); > - goto disable_clk; > - } > - > - usleep_range(1000, 2000); > - > - if (dsi->rst) { > - err = reset_control_deassert(dsi->rst); > - if (err < 0) { > - dev_err(dev, "cannot assert reset: %d\n", err); > - goto disable_clk_lp; > - } > - } > - > - return 0; > - > -disable_clk_lp: > - clk_disable_unprepare(dsi->clk_lp); > -disable_clk: > - clk_disable_unprepare(dsi->clk); > -disable_vdd: > - regulator_disable(dsi->vdd); > - return err; > -} > -#endif > - > -static const struct dev_pm_ops tegra_dsi_pm_ops = { > - SET_RUNTIME_PM_OPS(tegra_dsi_suspend, tegra_dsi_resume, NULL) > -}; > - > static const struct of_device_id tegra_dsi_of_match[] = { > { .compatible = "nvidia,tegra210-dsi", }, > { .compatible = "nvidia,tegra132-dsi", }, > @@ -1682,7 +1702,6 @@ struct platform_driver tegra_dsi_driver = { > .driver = { > .name = "tegra-dsi", > .of_match_table = tegra_dsi_of_match, > - .pm = &tegra_dsi_pm_ops, > }, > .probe = tegra_dsi_probe, > .remove = tegra_dsi_remove, > diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c > index 38bf1d16095f..cb504ec8f284 100644 > --- a/drivers/gpu/drm/tegra/hdmi.c > +++ b/drivers/gpu/drm/tegra/hdmi.c > @@ -1146,6 +1146,7 @@ static void tegra_hdmi_encoder_disable(struct drm_encoder *encoder) > struct tegra_dc *dc = to_tegra_dc(encoder->crtc); > struct tegra_hdmi *hdmi = to_hdmi(output); > u32 value; > + int err; > > /* > * The following accesses registers of the display controller, so make > @@ -1171,7 +1172,9 @@ static void tegra_hdmi_encoder_disable(struct drm_encoder *encoder) > tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_INT_ENABLE); > tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_INT_MASK); > > - pm_runtime_put(hdmi->dev); > + err = host1x_client_suspend(&hdmi->client); > + if (err < 0) > + dev_err(hdmi->dev, "failed to suspend: %d\n", err); > } > > static void tegra_hdmi_encoder_enable(struct drm_encoder *encoder) > @@ -1186,7 +1189,11 @@ static void tegra_hdmi_encoder_enable(struct drm_encoder *encoder) > u32 value; > int err; > > - pm_runtime_get_sync(hdmi->dev); > + err = host1x_client_resume(&hdmi->client); > + if (err < 0) { > + dev_err(hdmi->dev, "failed to resume: %d\n", err); > + return; > + } > > /* > * Enable and unmask the HDA codec SCRATCH0 register interrupt. This > @@ -1489,9 +1496,66 @@ static int tegra_hdmi_exit(struct host1x_client *client) > return 0; > } > > +static int tegra_hdmi_runtime_suspend(struct host1x_client *client) > +{ > + struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client); > + struct device *dev = client->dev; > + int err; > + > + err = reset_control_assert(hdmi->rst); > + if (err < 0) { > + dev_err(dev, "failed to assert reset: %d\n", err); > + return err; > + } > + > + usleep_range(1000, 2000); > + > + clk_disable_unprepare(hdmi->clk); > + pm_runtime_put_sync(dev); > + > + return 0; > +} > + > +static int tegra_hdmi_runtime_resume(struct host1x_client *client) > +{ > + struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client); > + struct device *dev = client->dev; > + int err; > + > + err = pm_runtime_get_sync(dev); > + if (err < 0) { > + dev_err(dev, "failed to get runtime PM: %d\n", err); > + return err; > + } > + > + err = clk_prepare_enable(hdmi->clk); > + if (err < 0) { > + dev_err(dev, "failed to enable clock: %d\n", err); > + goto put_rpm; > + } > + > + usleep_range(1000, 2000); > + > + err = reset_control_deassert(hdmi->rst); > + if (err < 0) { > + dev_err(dev, "failed to deassert reset: %d\n", err); > + goto disable_clk; > + } > + > + return 0; > + > +disable_clk: > + clk_disable_unprepare(hdmi->clk); > +put_rpm: > + pm_runtime_put_sync(dev); > + return err; > +} > + > static const struct host1x_client_ops hdmi_client_ops = { > .init = tegra_hdmi_init, > .exit = tegra_hdmi_exit, > + .suspend = tegra_hdmi_runtime_suspend, > + .resume = tegra_hdmi_runtime_resume, > }; > > static const struct tegra_hdmi_config tegra20_hdmi_config = { > @@ -1699,58 +1763,10 @@ static int tegra_hdmi_remove(struct platform_device *pdev) > return 0; > } > > -#ifdef CONFIG_PM > -static int tegra_hdmi_suspend(struct device *dev) > -{ > - struct tegra_hdmi *hdmi = dev_get_drvdata(dev); > - int err; > - > - err = reset_control_assert(hdmi->rst); > - if (err < 0) { > - dev_err(dev, "failed to assert reset: %d\n", err); > - return err; > - } > - > - usleep_range(1000, 2000); > - > - clk_disable_unprepare(hdmi->clk); > - > - return 0; > -} > - > -static int tegra_hdmi_resume(struct device *dev) > -{ > - struct tegra_hdmi *hdmi = dev_get_drvdata(dev); > - int err; > - > - err = clk_prepare_enable(hdmi->clk); > - if (err < 0) { > - dev_err(dev, "failed to enable clock: %d\n", err); > - return err; > - } > - > - usleep_range(1000, 2000); > - > - err = reset_control_deassert(hdmi->rst); > - if (err < 0) { > - dev_err(dev, "failed to deassert reset: %d\n", err); > - clk_disable_unprepare(hdmi->clk); > - return err; > - } > - > - return 0; > -} > -#endif > - > -static const struct dev_pm_ops tegra_hdmi_pm_ops = { > - SET_RUNTIME_PM_OPS(tegra_hdmi_suspend, tegra_hdmi_resume, NULL) > -}; > - > struct platform_driver tegra_hdmi_driver = { > .driver = { > .name = "tegra-hdmi", > .of_match_table = tegra_hdmi_of_match, > - .pm = &tegra_hdmi_pm_ops, > }, > .probe = tegra_hdmi_probe, > .remove = tegra_hdmi_remove, > diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c > index 5c7545ee5a5b..73e6fe9b833d 100644 > --- a/drivers/gpu/drm/tegra/hub.c > +++ b/drivers/gpu/drm/tegra/hub.c > @@ -105,17 +105,25 @@ static inline void tegra_plane_writel(struct tegra_plane *plane, u32 value, > > static int tegra_windowgroup_enable(struct tegra_windowgroup *wgrp) > { > + int err = 0; > + > mutex_lock(&wgrp->lock); > > if (wgrp->usecount == 0) { > - pm_runtime_get_sync(wgrp->parent); > + err = host1x_client_resume(wgrp->parent); > + if (err < 0) { > + dev_err(wgrp->parent->dev, "failed to resume: %d\n", err); > + goto unlock; > + } > + > reset_control_deassert(wgrp->rst); > } > > wgrp->usecount++; > - mutex_unlock(&wgrp->lock); > > - return 0; > +unlock: > + mutex_unlock(&wgrp->lock); > + return err; > } > > static void tegra_windowgroup_disable(struct tegra_windowgroup *wgrp) > @@ -131,7 +139,7 @@ static void tegra_windowgroup_disable(struct tegra_windowgroup *wgrp) > wgrp->index); > } > > - pm_runtime_put(wgrp->parent); > + host1x_client_suspend(wgrp->parent); > } > > wgrp->usecount--; > @@ -389,6 +397,7 @@ static void tegra_shared_plane_atomic_disable(struct drm_plane *plane, > struct tegra_plane *p = to_tegra_plane(plane); > struct tegra_dc *dc; > u32 value; > + int err; > > /* rien ne va plus */ > if (!old_state || !old_state->crtc) > @@ -396,6 +405,12 @@ static void tegra_shared_plane_atomic_disable(struct drm_plane *plane, > > dc = to_tegra_dc(old_state->crtc); > > + err = host1x_client_resume(&dc->client); > + if (err < 0) { > + dev_err(dc->dev, "failed to resume: %d\n", err); > + return; > + } > + > /* > * XXX Legacy helpers seem to sometimes call ->atomic_disable() even > * on planes that are already disabled. Make sure we fallback to the > @@ -404,15 +419,13 @@ static void tegra_shared_plane_atomic_disable(struct drm_plane *plane, > if (WARN_ON(p->dc == NULL)) > p->dc = dc; > > - pm_runtime_get_sync(dc->dev); > - > value = tegra_plane_readl(p, DC_WIN_WIN_OPTIONS); > value &= ~WIN_ENABLE; > tegra_plane_writel(p, value, DC_WIN_WIN_OPTIONS); > > tegra_dc_remove_shared_plane(dc, p); > > - pm_runtime_put(dc->dev); > + host1x_client_suspend(&dc->client); > } > > static void tegra_shared_plane_atomic_update(struct drm_plane *plane, > @@ -425,6 +438,7 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane, > struct tegra_plane *p = to_tegra_plane(plane); > dma_addr_t base; > u32 value; > + int err; > > /* rien ne va plus */ > if (!plane->state->crtc || !plane->state->fb) > @@ -435,7 +449,11 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane, > return; > } > > - pm_runtime_get_sync(dc->dev); > + err = host1x_client_resume(&dc->client); > + if (err < 0) { > + dev_err(dc->dev, "failed to resume: %d\n", err); > + return; > + } > > tegra_dc_assign_shared_plane(dc, p); > > @@ -525,7 +543,7 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane, > value &= ~CONTROL_CSC_ENABLE; > tegra_plane_writel(p, value, DC_WIN_WINDOW_SET_CONTROL); > > - pm_runtime_put(dc->dev); > + host1x_client_suspend(&dc->client); > } > > static const struct drm_plane_helper_funcs tegra_shared_plane_helper_funcs = { > @@ -561,7 +579,7 @@ struct drm_plane *tegra_shared_plane_create(struct drm_device *drm, > plane->base.index = index; > > plane->wgrp = &hub->wgrps[wgrp]; > - plane->wgrp->parent = dc->dev; > + plane->wgrp->parent = &dc->client; > > p = &plane->base.base; > > @@ -666,8 +684,13 @@ int tegra_display_hub_atomic_check(struct drm_device *drm, > static void tegra_display_hub_update(struct tegra_dc *dc) > { > u32 value; > + int err; > > - pm_runtime_get_sync(dc->dev); > + err = host1x_client_resume(&dc->client); > + if (err < 0) { > + dev_err(dc->dev, "failed to resume: %d\n", err); > + return; > + } > > value = tegra_dc_readl(dc, DC_CMD_IHUB_COMMON_MISC_CTL); > value &= ~LATENCY_EVENT; > @@ -682,7 +705,7 @@ static void tegra_display_hub_update(struct tegra_dc *dc) > tegra_dc_writel(dc, COMMON_ACTREQ, DC_CMD_STATE_CONTROL); > tegra_dc_readl(dc, DC_CMD_STATE_CONTROL); > > - pm_runtime_put(dc->dev); > + host1x_client_suspend(&dc->client); > } > > void tegra_display_hub_atomic_commit(struct drm_device *drm, > @@ -742,9 +765,85 @@ static int tegra_display_hub_exit(struct host1x_client *client) > return 0; > } > > +static int tegra_display_hub_runtime_suspend(struct host1x_client *client) > +{ > + struct tegra_display_hub *hub = to_tegra_display_hub(client); > + struct device *dev = client->dev; > + unsigned int i = hub->num_heads; > + int err; > + > + err = reset_control_assert(hub->rst); > + if (err < 0) > + return err; > + > + while (i--) > + clk_disable_unprepare(hub->clk_heads[i]); > + > + clk_disable_unprepare(hub->clk_hub); > + clk_disable_unprepare(hub->clk_dsc); > + clk_disable_unprepare(hub->clk_disp); > + > + pm_runtime_put_sync(dev); > + > + return 0; > +} > + > +static int tegra_display_hub_runtime_resume(struct host1x_client *client) > +{ > + struct tegra_display_hub *hub = to_tegra_display_hub(client); > + struct device *dev = client->dev; > + unsigned int i; > + int err; > + > + err = pm_runtime_get_sync(dev); > + if (err < 0) { > + dev_err(dev, "failed to get runtime PM: %d\n", err); > + return err; > + } > + > + err = clk_prepare_enable(hub->clk_disp); > + if (err < 0) > + goto put_rpm; > + > + err = clk_prepare_enable(hub->clk_dsc); > + if (err < 0) > + goto disable_disp; > + > + err = clk_prepare_enable(hub->clk_hub); > + if (err < 0) > + goto disable_dsc; > + > + for (i = 0; i < hub->num_heads; i++) { > + err = clk_prepare_enable(hub->clk_heads[i]); > + if (err < 0) > + goto disable_heads; > + } > + > + err = reset_control_deassert(hub->rst); > + if (err < 0) > + goto disable_heads; > + > + return 0; > + > +disable_heads: > + while (i--) > + clk_disable_unprepare(hub->clk_heads[i]); > + > + clk_disable_unprepare(hub->clk_hub); > +disable_dsc: > + clk_disable_unprepare(hub->clk_dsc); > +disable_disp: > + clk_disable_unprepare(hub->clk_disp); > +put_rpm: > + pm_runtime_put_sync(dev); > + return err; > +} > + > static const struct host1x_client_ops tegra_display_hub_ops = { > .init = tegra_display_hub_init, > .exit = tegra_display_hub_exit, > + .suspend = tegra_display_hub_runtime_suspend, > + .resume = tegra_display_hub_runtime_resume, > }; > > static int tegra_display_hub_probe(struct platform_device *pdev) > @@ -861,6 +960,7 @@ static int tegra_display_hub_probe(struct platform_device *pdev) > static int tegra_display_hub_remove(struct platform_device *pdev) > { > struct tegra_display_hub *hub = platform_get_drvdata(pdev); > + unsigned int i; > int err; > > err = host1x_client_unregister(&hub->client); > @@ -869,78 +969,17 @@ static int tegra_display_hub_remove(struct platform_device *pdev) > err); > } > > - pm_runtime_disable(&pdev->dev); > - > - return err; > -} > - > -static int __maybe_unused tegra_display_hub_suspend(struct device *dev) > -{ > - struct tegra_display_hub *hub = dev_get_drvdata(dev); > - unsigned int i = hub->num_heads; > - int err; > - > - err = reset_control_assert(hub->rst); > - if (err < 0) > - return err; > - > - while (i--) > - clk_disable_unprepare(hub->clk_heads[i]); > - > - clk_disable_unprepare(hub->clk_hub); > - clk_disable_unprepare(hub->clk_dsc); > - clk_disable_unprepare(hub->clk_disp); > - > - return 0; > -} > - > -static int __maybe_unused tegra_display_hub_resume(struct device *dev) > -{ > - struct tegra_display_hub *hub = dev_get_drvdata(dev); > - unsigned int i; > - int err; > - > - err = clk_prepare_enable(hub->clk_disp); > - if (err < 0) > - return err; > - > - err = clk_prepare_enable(hub->clk_dsc); > - if (err < 0) > - goto disable_disp; > - > - err = clk_prepare_enable(hub->clk_hub); > - if (err < 0) > - goto disable_dsc; > + for (i = 0; i < hub->soc->num_wgrps; i++) { > + struct tegra_windowgroup *wgrp = &hub->wgrps[i]; > > - for (i = 0; i < hub->num_heads; i++) { > - err = clk_prepare_enable(hub->clk_heads[i]); > - if (err < 0) > - goto disable_heads; > + mutex_destroy(&wgrp->lock); > } > > - err = reset_control_deassert(hub->rst); > - if (err < 0) > - goto disable_heads; > - > - return 0; > - > -disable_heads: > - while (i--) > - clk_disable_unprepare(hub->clk_heads[i]); > + pm_runtime_disable(&pdev->dev); > > - clk_disable_unprepare(hub->clk_hub); > -disable_dsc: > - clk_disable_unprepare(hub->clk_dsc); > -disable_disp: > - clk_disable_unprepare(hub->clk_disp); > return err; > } > > -static const struct dev_pm_ops tegra_display_hub_pm_ops = { > - SET_RUNTIME_PM_OPS(tegra_display_hub_suspend, > - tegra_display_hub_resume, NULL) > -}; > - > static const struct tegra_display_hub_soc tegra186_display_hub = { > .num_wgrps = 6, > .supports_dsc = true, > @@ -968,7 +1007,6 @@ struct platform_driver tegra_display_hub_driver = { > .driver = { > .name = "tegra-display-hub", > .of_match_table = tegra_display_hub_of_match, > - .pm = &tegra_display_hub_pm_ops, > }, > .probe = tegra_display_hub_probe, > .remove = tegra_display_hub_remove, > diff --git a/drivers/gpu/drm/tegra/hub.h b/drivers/gpu/drm/tegra/hub.h > index 767a60d9313c..3efa1be07ff8 100644 > --- a/drivers/gpu/drm/tegra/hub.h > +++ b/drivers/gpu/drm/tegra/hub.h > @@ -17,7 +17,7 @@ struct tegra_windowgroup { > struct mutex lock; > > unsigned int index; > - struct device *parent; > + struct host1x_client *parent; > struct reset_control *rst; > }; > > diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c > index 956bf5d680ad..200d99e17afe 100644 > --- a/drivers/gpu/drm/tegra/sor.c > +++ b/drivers/gpu/drm/tegra/sor.c > @@ -2255,7 +2255,7 @@ static void tegra_sor_hdmi_disable(struct drm_encoder *encoder) > if (err < 0) > dev_err(sor->dev, "failed to power off I/O pad: %d\n", err); > > - pm_runtime_put(sor->dev); > + host1x_client_suspend(&sor->client); > } > > static void tegra_sor_hdmi_enable(struct drm_encoder *encoder) > @@ -2276,7 +2276,11 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder) > mode = &encoder->crtc->state->adjusted_mode; > pclk = mode->clock * 1000; > > - pm_runtime_get_sync(sor->dev); > + err = host1x_client_resume(&sor->client); > + if (err < 0) { > + dev_err(sor->dev, "failed to resume: %d\n", err); > + return; > + } > > /* switch to safe parent clock */ > err = tegra_sor_set_parent_clock(sor, sor->clk_safe); > @@ -2722,7 +2726,7 @@ static void tegra_sor_dp_disable(struct drm_encoder *encoder) > if (output->panel) > drm_panel_unprepare(output->panel); > > - pm_runtime_put(sor->dev); > + host1x_client_suspend(&sor->client); > } > > static void tegra_sor_dp_enable(struct drm_encoder *encoder) > @@ -2742,7 +2746,11 @@ static void tegra_sor_dp_enable(struct drm_encoder *encoder) > mode = &encoder->crtc->state->adjusted_mode; > info = &output->connector.display_info; > > - pm_runtime_get_sync(sor->dev); > + err = host1x_client_resume(&sor->client); > + if (err < 0) { > + dev_err(sor->dev, "failed to resume: %d\n", err); > + return; > + } > > /* switch to safe parent clock */ > err = tegra_sor_set_parent_clock(sor, sor->clk_safe); > @@ -3189,9 +3197,80 @@ static int tegra_sor_exit(struct host1x_client *client) > return 0; > } > > +static int tegra_sor_runtime_suspend(struct host1x_client *client) > +{ > + struct tegra_sor *sor = host1x_client_to_sor(client); > + struct device *dev = client->dev; > + int err; > + > + if (sor->rst) { > + err = reset_control_assert(sor->rst); > + if (err < 0) { > + dev_err(dev, "failed to assert reset: %d\n", err); > + return err; > + } > + > + reset_control_release(sor->rst); > + } > + > + usleep_range(1000, 2000); > + > + clk_disable_unprepare(sor->clk); > + pm_runtime_put_sync(dev); > + > + return 0; > +} > + > +static int tegra_sor_runtime_resume(struct host1x_client *client) > +{ > + struct tegra_sor *sor = host1x_client_to_sor(client); > + struct device *dev = client->dev; > + int err; > + > + err = pm_runtime_get_sync(dev); > + if (err < 0) { > + dev_err(dev, "failed to get runtime PM: %d\n", err); > + return err; > + } > + > + err = clk_prepare_enable(sor->clk); > + if (err < 0) { > + dev_err(dev, "failed to enable clock: %d\n", err); > + goto put_rpm; > + } > + > + usleep_range(1000, 2000); > + > + if (sor->rst) { > + err = reset_control_acquire(sor->rst); > + if (err < 0) { > + dev_err(dev, "failed to acquire reset: %d\n", err); > + goto disable_clk; > + } > + > + err = reset_control_deassert(sor->rst); > + if (err < 0) { > + dev_err(dev, "failed to deassert reset: %d\n", err); > + goto release_reset; > + } > + } > + > + return 0; > + > +release_reset: > + reset_control_release(sor->rst); > +disable_clk: > + clk_disable_unprepare(sor->clk); > +put_rpm: > + pm_runtime_put_sync(dev); > + return err; > +} > + > static const struct host1x_client_ops sor_client_ops = { > .init = tegra_sor_init, > .exit = tegra_sor_exit, > + .suspend = tegra_sor_runtime_suspend, > + .resume = tegra_sor_runtime_resume, > }; > > static const u8 tegra124_sor_xbar_cfg[5] = { > @@ -3842,10 +3921,9 @@ static int tegra_sor_probe(struct platform_device *pdev) > if (!sor->clk_pad) { > char *name; > > - err = pm_runtime_get_sync(&pdev->dev); > + err = host1x_client_resume(&sor->client); > if (err < 0) { > - dev_err(&pdev->dev, "failed to get runtime PM: %d\n", > - err); > + dev_err(sor->dev, "failed to resume: %d\n", err); > goto remove; > } > > @@ -3856,7 +3934,7 @@ static int tegra_sor_probe(struct platform_device *pdev) > } > > sor->clk_pad = tegra_clk_sor_pad_register(sor, name); > - pm_runtime_put(&pdev->dev); > + host1x_client_suspend(&sor->client); > } > > if (IS_ERR(sor->clk_pad)) { > @@ -3912,61 +3990,6 @@ static int tegra_sor_remove(struct platform_device *pdev) > return 0; > } > > -static int tegra_sor_runtime_suspend(struct device *dev) > -{ > - struct tegra_sor *sor = dev_get_drvdata(dev); > - int err; > - > - if (sor->rst) { > - err = reset_control_assert(sor->rst); > - if (err < 0) { > - dev_err(dev, "failed to assert reset: %d\n", err); > - return err; > - } > - > - reset_control_release(sor->rst); > - } > - > - usleep_range(1000, 2000); > - > - clk_disable_unprepare(sor->clk); > - > - return 0; > -} > - > -static int tegra_sor_runtime_resume(struct device *dev) > -{ > - struct tegra_sor *sor = dev_get_drvdata(dev); > - int err; > - > - err = clk_prepare_enable(sor->clk); > - if (err < 0) { > - dev_err(dev, "failed to enable clock: %d\n", err); > - return err; > - } > - > - usleep_range(1000, 2000); > - > - if (sor->rst) { > - err = reset_control_acquire(sor->rst); > - if (err < 0) { > - dev_err(dev, "failed to acquire reset: %d\n", err); > - clk_disable_unprepare(sor->clk); > - return err; > - } > - > - err = reset_control_deassert(sor->rst); > - if (err < 0) { > - dev_err(dev, "failed to deassert reset: %d\n", err); > - reset_control_release(sor->rst); > - clk_disable_unprepare(sor->clk); > - return err; > - } > - } > - > - return 0; > -} > - > static int tegra_sor_suspend(struct device *dev) > { > struct tegra_sor *sor = dev_get_drvdata(dev); > @@ -3974,8 +3997,9 @@ static int tegra_sor_suspend(struct device *dev) > > if (sor->hdmi_supply) { > err = regulator_disable(sor->hdmi_supply); > - if (err < 0) > + if (err < 0) { > return err; > + } > } > > return 0; > @@ -3996,8 +4020,6 @@ static int tegra_sor_resume(struct device *dev) > } > > static const struct dev_pm_ops tegra_sor_pm_ops = { > - SET_RUNTIME_PM_OPS(tegra_sor_runtime_suspend, tegra_sor_runtime_resume, > - NULL) > SET_SYSTEM_SLEEP_PM_OPS(tegra_sor_suspend, tegra_sor_resume) > }; > > diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c > index ade56b860cf9..678961ada17f 100644 > --- a/drivers/gpu/drm/tegra/vic.c > +++ b/drivers/gpu/drm/tegra/vic.c > @@ -52,48 +52,6 @@ static void vic_writel(struct vic *vic, u32 value, unsigned int offset) > writel(value, vic->regs + offset); > } > > -static int vic_runtime_resume(struct device *dev) > -{ > - struct vic *vic = dev_get_drvdata(dev); > - int err; > - > - err = clk_prepare_enable(vic->clk); > - if (err < 0) > - return err; > - > - usleep_range(10, 20); > - > - err = reset_control_deassert(vic->rst); > - if (err < 0) > - goto disable; > - > - usleep_range(10, 20); > - > - return 0; > - > -disable: > - clk_disable_unprepare(vic->clk); > - return err; > -} > - > -static int vic_runtime_suspend(struct device *dev) > -{ > - struct vic *vic = dev_get_drvdata(dev); > - int err; > - > - err = reset_control_assert(vic->rst); > - if (err < 0) > - return err; > - > - usleep_range(2000, 4000); > - > - clk_disable_unprepare(vic->clk); > - > - vic->booted = false; > - > - return 0; > -} > - > static int vic_boot(struct vic *vic) > { > #ifdef CONFIG_IOMMU_API > @@ -240,9 +198,62 @@ static int vic_exit(struct host1x_client *client) > return 0; > } > > +static int vic_runtime_suspend(struct host1x_client *client) > +{ > + struct tegra_drm_client *drm = host1x_to_drm_client(client); > + struct vic *vic = to_vic(drm); > + int err; > + > + err = reset_control_assert(vic->rst); > + if (err < 0) > + return err; > + > + usleep_range(2000, 4000); > + > + clk_disable_unprepare(vic->clk); > + pm_runtime_put_sync(vic->dev); > + > + vic->booted = false; > + > + return 0; > +} > + > +static int vic_runtime_resume(struct host1x_client *client) > +{ > + struct tegra_drm_client *drm = host1x_to_drm_client(client); > + struct vic *vic = to_vic(drm); > + int err; > + > + err = pm_runtime_get_sync(vic->dev); > + if (err < 0) > + return err; > + > + err = clk_prepare_enable(vic->clk); > + if (err < 0) > + goto put_rpm; > + > + usleep_range(10, 20); > + > + err = reset_control_deassert(vic->rst); > + if (err < 0) > + goto disable; > + > + usleep_range(10, 20); > + > + return 0; > + > +put_rpm: > + pm_runtime_put_sync(vic->dev); > +disable: > + clk_disable_unprepare(vic->clk); > + return err; > +} > + > static const struct host1x_client_ops vic_client_ops = { > .init = vic_init, > .exit = vic_exit, > + .suspend = vic_runtime_suspend, > + .resume = vic_runtime_resume, > }; > > static int vic_load_firmware(struct vic *vic) > @@ -314,38 +325,37 @@ static int vic_open_channel(struct tegra_drm_client *client, > struct vic *vic = to_vic(client); > int err; > > - err = pm_runtime_get_sync(vic->dev); > + err = host1x_client_resume(&client->base); > if (err < 0) > return err; > > err = vic_load_firmware(vic); > if (err < 0) > - goto rpm_put; > + goto suspend; > > err = vic_boot(vic); > if (err < 0) > - goto rpm_put; > + goto suspend; > > context->channel = host1x_channel_get(vic->channel); > if (!context->channel) { > err = -ENOMEM; > - goto rpm_put; > + goto suspend; > } > > return 0; > > -rpm_put: > - pm_runtime_put(vic->dev); > +suspend: > + host1x_client_suspend(&client->base); > return err; > } > > static void vic_close_channel(struct tegra_drm_context *context) > { > - struct vic *vic = to_vic(context->client); > + struct host1x_client *client = &context->client->base; > > host1x_channel_put(context->channel); > - > - pm_runtime_put(vic->dev); > + host1x_client_suspend(client); > } > > static const struct tegra_drm_client_ops vic_ops = { > @@ -472,16 +482,9 @@ static int vic_probe(struct platform_device *pdev) > } > > pm_runtime_enable(&pdev->dev); > - if (!pm_runtime_enabled(&pdev->dev)) { > - err = vic_runtime_resume(&pdev->dev); > - if (err < 0) > - goto unregister_client; > - } > > return 0; > > -unregister_client: > - host1x_client_unregister(&vic->client.base); > exit_falcon: > falcon_exit(&vic->falcon); > > @@ -493,6 +496,8 @@ static int vic_remove(struct platform_device *pdev) > struct vic *vic = platform_get_drvdata(pdev); > int err; > > + pm_runtime_disable(&pdev->dev); > + > err = host1x_client_unregister(&vic->client.base); > if (err < 0) { > dev_err(&pdev->dev, "failed to unregister host1x client: %d\n", > @@ -500,25 +505,15 @@ static int vic_remove(struct platform_device *pdev) > return err; > } > > - if (pm_runtime_enabled(&pdev->dev)) > - pm_runtime_disable(&pdev->dev); > - else > - vic_runtime_suspend(&pdev->dev); > - > falcon_exit(&vic->falcon); > > return 0; > } > > -static const struct dev_pm_ops vic_pm_ops = { > - SET_RUNTIME_PM_OPS(vic_runtime_suspend, vic_runtime_resume, NULL) > -}; > - > struct platform_driver tegra_vic_driver = { > .driver = { > .name = "tegra-vic", > .of_match_table = tegra_vic_of_match, > - .pm = &vic_pm_ops > }, > .probe = vic_probe, > .remove = vic_remove, > diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c > index 50d500345d04..6a995db51d6d 100644 > --- a/drivers/gpu/host1x/bus.c > +++ b/drivers/gpu/host1x/bus.c > @@ -710,6 +710,10 @@ int host1x_client_register(struct host1x_client *client) > struct host1x *host1x; > int err; > > + INIT_LIST_HEAD(&client->list); > + mutex_init(&client->lock); > + client->usecount = 0; > + > mutex_lock(&devices_lock); > > list_for_each_entry(host1x, &devices, list) { > @@ -768,3 +772,74 @@ int host1x_client_unregister(struct host1x_client *client) > return 0; > } > EXPORT_SYMBOL(host1x_client_unregister); > + > +int host1x_client_suspend(struct host1x_client *client) > +{ > + int err = 0; > + > + mutex_lock(&client->lock); > + > + if (client->usecount == 1) { > + if (client->ops && client->ops->suspend) { > + err = client->ops->suspend(client); > + if (err < 0) > + goto unlock; > + } > + } > + > + client->usecount--; > + dev_dbg(client->dev, "use count: %u\n", client->usecount); > + > + if (client->parent) { > + err = host1x_client_suspend(client->parent); > + if (err < 0) > + goto resume; > + } > + > + goto unlock; > + > +resume: > + if (client->usecount == 0) > + if (client->ops && client->ops->resume) > + client->ops->resume(client); > + > + client->usecount++; > +unlock: > + mutex_unlock(&client->lock); > + return err; > +} > +EXPORT_SYMBOL(host1x_client_suspend); > + > +int host1x_client_resume(struct host1x_client *client) > +{ > + int err = 0; > + > + mutex_lock(&client->lock); > + > + if (client->parent) { > + err = host1x_client_resume(client->parent); > + if (err < 0) > + goto unlock; > + } > + > + if (client->usecount == 0) { > + if (client->ops && client->ops->resume) { > + err = client->ops->resume(client); > + if (err < 0) > + goto suspend; > + } > + } > + > + client->usecount++; > + dev_dbg(client->dev, "use count: %u\n", client->usecount); > + > + goto unlock; > + > +suspend: > + if (client->parent) > + host1x_client_suspend(client->parent); > +unlock: > + mutex_unlock(&client->lock); > + return err; > +} > +EXPORT_SYMBOL(host1x_client_resume); > diff --git a/include/linux/host1x.h b/include/linux/host1x.h > index 470a193a9fed..0254ebcdc0a7 100644 > --- a/include/linux/host1x.h > +++ b/include/linux/host1x.h > @@ -24,10 +24,14 @@ struct iommu_group; > * struct host1x_client_ops - host1x client operations > * @init: host1x client initialization code > * @exit: host1x client tear down code > + * @suspend: host1x client suspend code > + * @resume: host1x client resume code > */ > struct host1x_client_ops { > int (*init)(struct host1x_client *client); > int (*exit)(struct host1x_client *client); > + int (*suspend)(struct host1x_client *client); > + int (*resume)(struct host1x_client *client); > }; > > /** > @@ -55,6 +59,10 @@ struct host1x_client { > > struct host1x_syncpt **syncpts; > unsigned int num_syncpts; > + > + struct host1x_client *parent; > + unsigned int usecount; > + struct mutex lock; > }; > > /* > @@ -309,6 +317,9 @@ int host1x_device_exit(struct host1x_device *device); > int host1x_client_register(struct host1x_client *client); > int host1x_client_unregister(struct host1x_client *client); > > +int host1x_client_suspend(struct host1x_client *client); > +int host1x_client_resume(struct host1x_client *client); > + > struct tegra_mipi_device; > > struct tegra_mipi_device *tegra_mipi_request(struct device *device); >