From mboxrd@z Thu Jan 1 00:00:00 1970 From: Thierry Reding Subject: [PATCH 2/2] drm/tegra: Do not implement runtime PM Date: Tue, 3 Dec 2019 17:27:33 +0100 Message-ID: <20191203162733.1436800-2-thierry.reding@gmail.com> References: <20191203162733.1436800-1-thierry.reding@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20191203162733.1436800-1-thierry.reding@gmail.com> 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 RnJvbTogVGhpZXJyeSBSZWRpbmcgPHRyZWRpbmdAbnZpZGlhLmNvbT4KClRoZSBUZWdyYSBEUk0g ZHJpdmVyIGhlYXZpbHkgcmVsaWVzIG9uIHRoZSBpbXBsZW1lbnRhdGlvbnMgZm9yIHJ1bnRpbWUK c3VzcGVuZC9yZXN1bWUgdG8gYmUgY2FsbGVkIGF0IHNwZWNpZmljIHRpbWVzLiBVbmZvcnR1bmF0 ZWx5LCB0aGVyZSBhcmUKc29tZSBjYXNlcyB3aGVyZSB0aGF0IGRvZXNuJ3Qgd29yay4gT25lIGV4 YW1wbGUgaXMgaWYgdGhlIHVzZXIgZGlzYWJsZXMKcnVudGltZSBQTSBmb3IgYSBnaXZlbiBzdWJk ZXZpY2UuIEFub3RoZXIgZXhhbXBsZSBpcyB0aGF0IHRoZSBQTSBjb3JlCmFjcXVpcmVzIGEgcmVm ZXJlbmNlIHRvIHJ1bnRpbWUgUE0gZHVyaW5nIHN5c3RlbSBzbGVlcCwgZWZmZWN0aXZlbHkKcHJl dmVudGluZyBkZXZpY2VzIGZyb20gZ29pbmcgaW50byBsb3cgcG93ZXIgbW9kZXMuIFRoaXMgaXMg aW50ZW50aW9uYWwKdG8gYXZvaWQgbmFzdHkgcmFjZSBjb25kaXRpb25zLCBidXQgaXQgYWxzbyBj YXVzZXMgc3lzdGVtIHNsZWVwIHRvIG5vdApmdW5jdGlvbiBwcm9wZXJseSBvbiBhbGwgVGVncmEg c3lzdGVtcy4KCkZpeCB0aGlzIGJ5IG5vdCBpbXBsZW1lbnRpbmcgcnVudGltZSBQTSBhdCBhbGwu IEluc3RlYWQsIGEgbWluaW1hbCwKcmVmZXJlbmNlLWNvdW50ZWQgc3VzcGVuZC9yZXN1bWUgaW5m cmFzdHJ1Y3R1cmUgaXMgYWRkZWQgdG8gdGhlIGhvc3QxeApidXMuIFRoaXMgaGFzIHRoZSBiZW5l Zml0IHRoYXQgaXQgY2FuIGJlIHVzZWQgcmVnYXJkbGVzcyBvZiB0aGUgc3lzdGVtCnBvd2VyIHN0 YXRlIChvciBhbnkgdHJhbnNpdGlvbnMgd2UgbWlnaHQgYmUgaW4pLCBvciB3aGV0aGVyIG9yIG5v dCB0aGUKdXNlciBhbGxvd3MgcnVudGltZSBQTS4KCkF0b21pYyBtb2Rlc2V0dGluZyBndWFyYW50 ZWVzIHRoYXQgdGhlc2UgZnVuY3Rpb25zIHdpbGwgZW5kIHVwIGJlaW5nCmNhbGxlZCBhdCB0aGUg cmlnaHQgcG9pbnQgaW4gdGltZSwgc28gdGhlIHBpdGZhbGxzIGZvciB0aGUgbW9yZSBnZW5lcmlj CnJ1bnRpbWUgUE0gZG8gbm90IGFwcGx5IGhlcmUuCgpTaWduZWQtb2ZmLWJ5OiBUaGllcnJ5IFJl ZGluZyA8dHJlZGluZ0BudmlkaWEuY29tPgotLS0KIGRyaXZlcnMvZ3B1L2RybS90ZWdyYS9kYy5j ICAgIHwgMTQxICsrKysrKysrKysrKysrLS0tLS0tLS0tLQogZHJpdmVycy9ncHUvZHJtL3RlZ3Jh L2RwYXV4LmMgfCAgIDIgKy0KIGRyaXZlcnMvZ3B1L2RybS90ZWdyYS9kcm0uaCAgIHwgICAyICsK IGRyaXZlcnMvZ3B1L2RybS90ZWdyYS9kc2kuYyAgIHwgMTc1ICsrKysrKysrKysrKysrKystLS0t LS0tLS0tLS0tLQogZHJpdmVycy9ncHUvZHJtL3RlZ3JhL2hkbWkuYyAgfCAxMTYgKysrKysrKysr KystLS0tLS0tLS0KIGRyaXZlcnMvZ3B1L2RybS90ZWdyYS9odWIuYyAgIHwgMTk0ICsrKysrKysr KysrKysrKysrKysrLS0tLS0tLS0tLS0tLS0KIGRyaXZlcnMvZ3B1L2RybS90ZWdyYS9odWIuaCAg IHwgICAyICstCiBkcml2ZXJzL2dwdS9kcm0vdGVncmEvc29yLmMgICB8IDE1NCArKysrKysrKysr KysrKystLS0tLS0tLS0tLS0KIGRyaXZlcnMvZ3B1L2RybS90ZWdyYS92aWMuYyAgIHwgMTMxICsr KysrKysrKysrLS0tLS0tLS0tLS0tCiBkcml2ZXJzL2dwdS9ob3N0MXgvYnVzLmMgICAgICB8ICA3 NSArKysrKysrKysrKysrCiBpbmNsdWRlL2xpbnV4L2hvc3QxeC5oICAgICAgICB8ICAxMSArKwog MTEgZmlsZXMgY2hhbmdlZCwgNjA0IGluc2VydGlvbnMoKyksIDM5OSBkZWxldGlvbnMoLSkKCmRp ZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vdGVncmEvZGMuYyBiL2RyaXZlcnMvZ3B1L2RybS90 ZWdyYS9kYy5jCmluZGV4IDI5ODNlYjMzZjJiZS4uODcxMDQ2ZjNmNDY5IDEwMDY0NAotLS0gYS9k cml2ZXJzL2dwdS9kcm0vdGVncmEvZGMuYworKysgYi9kcml2ZXJzL2dwdS9kcm0vdGVncmEvZGMu YwpAQCAtMTczNyw2ICsxNzM3LDcgQEAgc3RhdGljIHZvaWQgdGVncmFfY3J0Y19hdG9taWNfZGlz YWJsZShzdHJ1Y3QgZHJtX2NydGMgKmNydGMsCiB7CiAJc3RydWN0IHRlZ3JhX2RjICpkYyA9IHRv X3RlZ3JhX2RjKGNydGMpOwogCXUzMiB2YWx1ZTsKKwlpbnQgZXJyOwogCiAJaWYgKCF0ZWdyYV9k Y19pZGxlKGRjKSkgewogCQl0ZWdyYV9kY19zdG9wKGRjKTsKQEAgLTE3ODMsNyArMTc4NCw5IEBA IHN0YXRpYyB2b2lkIHRlZ3JhX2NydGNfYXRvbWljX2Rpc2FibGUoc3RydWN0IGRybV9jcnRjICpj cnRjLAogCiAJc3Bpbl91bmxvY2tfaXJxKCZjcnRjLT5kZXYtPmV2ZW50X2xvY2spOwogCi0JcG1f cnVudGltZV9wdXRfc3luYyhkYy0+ZGV2KTsKKwllcnIgPSBob3N0MXhfY2xpZW50X3N1c3BlbmQo JmRjLT5jbGllbnQpOworCWlmIChlcnIgPCAwKQorCQlkZXZfZXJyKGRjLT5kZXYsICJmYWlsZWQg dG8gc3VzcGVuZDogJWRcbiIsIGVycik7CiB9CiAKIHN0YXRpYyB2b2lkIHRlZ3JhX2NydGNfYXRv bWljX2VuYWJsZShzdHJ1Y3QgZHJtX2NydGMgKmNydGMsCkBAIC0xNzkzLDggKzE3OTYsMTMgQEAg c3RhdGljIHZvaWQgdGVncmFfY3J0Y19hdG9taWNfZW5hYmxlKHN0cnVjdCBkcm1fY3J0YyAqY3J0 YywKIAlzdHJ1Y3QgdGVncmFfZGNfc3RhdGUgKnN0YXRlID0gdG9fZGNfc3RhdGUoY3J0Yy0+c3Rh dGUpOwogCXN0cnVjdCB0ZWdyYV9kYyAqZGMgPSB0b190ZWdyYV9kYyhjcnRjKTsKIAl1MzIgdmFs dWU7CisJaW50IGVycjsKIAotCXBtX3J1bnRpbWVfZ2V0X3N5bmMoZGMtPmRldik7CisJZXJyID0g aG9zdDF4X2NsaWVudF9yZXN1bWUoJmRjLT5jbGllbnQpOworCWlmIChlcnIgPCAwKSB7CisJCWRl dl9lcnIoZGMtPmRldiwgImZhaWxlZCB0byByZXN1bWU6ICVkXG4iLCBlcnIpOworCQlyZXR1cm47 CisJfQogCiAJLyogaW5pdGlhbGl6ZSBkaXNwbGF5IGNvbnRyb2xsZXIgKi8KIAlpZiAoZGMtPnN5 bmNwdCkgewpAQCAtMjAyMiw2ICsyMDMwLDE1IEBAIHN0YXRpYyBpbnQgdGVncmFfZGNfaW5pdChz dHJ1Y3QgaG9zdDF4X2NsaWVudCAqY2xpZW50KQogCWlmICghdGVncmFfZGNfaGFzX3dpbmRvd19n cm91cHMoZGMpKQogCQlyZXR1cm4gMDsKIAorCS8qCisJICogU2V0IHRoZSBkaXNwbGF5IGh1YiBh cyB0aGUgaG9zdDF4IGNsaWVudCBwYXJlbnQgZm9yIHRoZSBkaXNwbGF5CisJICogY29udHJvbGxl ci4gVGhpcyBpcyBuZWVkZWQgZm9yIHRoZSBydW50aW1lIHJlZmVyZW5jZSBjb3VudGluZyB0aGF0 CisJICogZW5zdXJlcyB0aGUgZGlzcGxheSBodWIgaXMgYWx3YXlzIHBvd2VyZWQgd2hlbiBhbnkg b2YgdGhlIGRpc3BsYXkKKwkgKiBjb250cm9sbGVycyBhcmUuCisJICovCisJaWYgKGRjLT5zb2Mt Pmhhc19udmRpc3BsYXkpCisJCWNsaWVudC0+cGFyZW50ID0gJnRlZ3JhLT5odWItPmNsaWVudDsK KwogCWRjLT5zeW5jcHQgPSBob3N0MXhfc3luY3B0X3JlcXVlc3QoY2xpZW50LCBmbGFncyk7CiAJ aWYgKCFkYy0+c3luY3B0KQogCQlkZXZfd2FybihkYy0+ZGV2LCAiZmFpbGVkIHRvIGFsbG9jYXRl IHN5bmNwb2ludFxuIik7CkBAIC0yMTMxLDkgKzIxNDgsNzQgQEAgc3RhdGljIGludCB0ZWdyYV9k Y19leGl0KHN0cnVjdCBob3N0MXhfY2xpZW50ICpjbGllbnQpCiAJcmV0dXJuIDA7CiB9CiAKK3N0 YXRpYyBpbnQgdGVncmFfZGNfcnVudGltZV9zdXNwZW5kKHN0cnVjdCBob3N0MXhfY2xpZW50ICpj bGllbnQpCit7CisJc3RydWN0IHRlZ3JhX2RjICpkYyA9IGhvc3QxeF9jbGllbnRfdG9fZGMoY2xp ZW50KTsKKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSBjbGllbnQtPmRldjsKKwlpbnQgZXJyOworCisJ ZXJyID0gcmVzZXRfY29udHJvbF9hc3NlcnQoZGMtPnJzdCk7CisJaWYgKGVyciA8IDApIHsKKwkJ ZGV2X2VycihkZXYsICJmYWlsZWQgdG8gYXNzZXJ0IHJlc2V0OiAlZFxuIiwgZXJyKTsKKwkJcmV0 dXJuIGVycjsKKwl9CisKKwlpZiAoZGMtPnNvYy0+aGFzX3Bvd2VyZ2F0ZSkKKwkJdGVncmFfcG93 ZXJnYXRlX3Bvd2VyX29mZihkYy0+cG93ZXJnYXRlKTsKKworCWNsa19kaXNhYmxlX3VucHJlcGFy ZShkYy0+Y2xrKTsKKwlwbV9ydW50aW1lX3B1dF9zeW5jKGRldik7CisKKwlyZXR1cm4gMDsKK30K Kworc3RhdGljIGludCB0ZWdyYV9kY19ydW50aW1lX3Jlc3VtZShzdHJ1Y3QgaG9zdDF4X2NsaWVu dCAqY2xpZW50KQoreworCXN0cnVjdCB0ZWdyYV9kYyAqZGMgPSBob3N0MXhfY2xpZW50X3RvX2Rj KGNsaWVudCk7CisJc3RydWN0IGRldmljZSAqZGV2ID0gY2xpZW50LT5kZXY7CisJaW50IGVycjsK KworCWVyciA9IHBtX3J1bnRpbWVfZ2V0X3N5bmMoZGV2KTsKKwlpZiAoZXJyIDwgMCkgeworCQlk ZXZfZXJyKGRldiwgImZhaWxlZCB0byBnZXQgcnVudGltZSBQTTogJWRcbiIsIGVycik7CisJCXJl dHVybiBlcnI7CisJfQorCisJaWYgKGRjLT5zb2MtPmhhc19wb3dlcmdhdGUpIHsKKwkJZXJyID0g dGVncmFfcG93ZXJnYXRlX3NlcXVlbmNlX3Bvd2VyX3VwKGRjLT5wb3dlcmdhdGUsIGRjLT5jbGss CisJCQkJCQkJZGMtPnJzdCk7CisJCWlmIChlcnIgPCAwKSB7CisJCQlkZXZfZXJyKGRldiwgImZh aWxlZCB0byBwb3dlciBwYXJ0aXRpb246ICVkXG4iLCBlcnIpOworCQkJZ290byBwdXRfcnBtOwor CQl9CisJfSBlbHNlIHsKKwkJZXJyID0gY2xrX3ByZXBhcmVfZW5hYmxlKGRjLT5jbGspOworCQlp ZiAoZXJyIDwgMCkgeworCQkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gZW5hYmxlIGNsb2NrOiAl ZFxuIiwgZXJyKTsKKwkJCWdvdG8gcHV0X3JwbTsKKwkJfQorCisJCWVyciA9IHJlc2V0X2NvbnRy b2xfZGVhc3NlcnQoZGMtPnJzdCk7CisJCWlmIChlcnIgPCAwKSB7CisJCQlkZXZfZXJyKGRldiwg ImZhaWxlZCB0byBkZWFzc2VydCByZXNldDogJWRcbiIsIGVycik7CisJCQlnb3RvIGRpc2FibGVf Y2xrOworCQl9CisJfQorCisJcmV0dXJuIDA7CisKK2Rpc2FibGVfY2xrOgorCWNsa19kaXNhYmxl X3VucHJlcGFyZShkYy0+Y2xrKTsKK3B1dF9ycG06CisJcG1fcnVudGltZV9wdXRfc3luYyhkZXYp OworCXJldHVybiBlcnI7Cit9CisKIHN0YXRpYyBjb25zdCBzdHJ1Y3QgaG9zdDF4X2NsaWVudF9v cHMgZGNfY2xpZW50X29wcyA9IHsKIAkuaW5pdCA9IHRlZ3JhX2RjX2luaXQsCiAJLmV4aXQgPSB0 ZWdyYV9kY19leGl0LAorCS5zdXNwZW5kID0gdGVncmFfZGNfcnVudGltZV9zdXNwZW5kLAorCS5y ZXN1bWUgPSB0ZWdyYV9kY19ydW50aW1lX3Jlc3VtZSwKIH07CiAKIHN0YXRpYyBjb25zdCBzdHJ1 Y3QgdGVncmFfZGNfc29jX2luZm8gdGVncmEyMF9kY19zb2NfaW5mbyA9IHsKQEAgLTI1NDUsNjUg KzI2MjcsMTAgQEAgc3RhdGljIGludCB0ZWdyYV9kY19yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2Rl dmljZSAqcGRldikKIAlyZXR1cm4gMDsKIH0KIAotI2lmZGVmIENPTkZJR19QTQotc3RhdGljIGlu dCB0ZWdyYV9kY19zdXNwZW5kKHN0cnVjdCBkZXZpY2UgKmRldikKLXsKLQlzdHJ1Y3QgdGVncmFf ZGMgKmRjID0gZGV2X2dldF9kcnZkYXRhKGRldik7Ci0JaW50IGVycjsKLQotCWVyciA9IHJlc2V0 X2NvbnRyb2xfYXNzZXJ0KGRjLT5yc3QpOwotCWlmIChlcnIgPCAwKSB7Ci0JCWRldl9lcnIoZGV2 LCAiZmFpbGVkIHRvIGFzc2VydCByZXNldDogJWRcbiIsIGVycik7Ci0JCXJldHVybiBlcnI7Ci0J fQotCi0JaWYgKGRjLT5zb2MtPmhhc19wb3dlcmdhdGUpCi0JCXRlZ3JhX3Bvd2VyZ2F0ZV9wb3dl cl9vZmYoZGMtPnBvd2VyZ2F0ZSk7Ci0KLQljbGtfZGlzYWJsZV91bnByZXBhcmUoZGMtPmNsayk7 Ci0KLQlyZXR1cm4gMDsKLX0KLQotc3RhdGljIGludCB0ZWdyYV9kY19yZXN1bWUoc3RydWN0IGRl dmljZSAqZGV2KQotewotCXN0cnVjdCB0ZWdyYV9kYyAqZGMgPSBkZXZfZ2V0X2RydmRhdGEoZGV2 KTsKLQlpbnQgZXJyOwotCi0JaWYgKGRjLT5zb2MtPmhhc19wb3dlcmdhdGUpIHsKLQkJZXJyID0g dGVncmFfcG93ZXJnYXRlX3NlcXVlbmNlX3Bvd2VyX3VwKGRjLT5wb3dlcmdhdGUsIGRjLT5jbGss Ci0JCQkJCQkJZGMtPnJzdCk7Ci0JCWlmIChlcnIgPCAwKSB7Ci0JCQlkZXZfZXJyKGRldiwgImZh aWxlZCB0byBwb3dlciBwYXJ0aXRpb246ICVkXG4iLCBlcnIpOwotCQkJcmV0dXJuIGVycjsKLQkJ fQotCX0gZWxzZSB7Ci0JCWVyciA9IGNsa19wcmVwYXJlX2VuYWJsZShkYy0+Y2xrKTsKLQkJaWYg KGVyciA8IDApIHsKLQkJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGVuYWJsZSBjbG9jazogJWRc biIsIGVycik7Ci0JCQlyZXR1cm4gZXJyOwotCQl9Ci0KLQkJZXJyID0gcmVzZXRfY29udHJvbF9k ZWFzc2VydChkYy0+cnN0KTsKLQkJaWYgKGVyciA8IDApIHsKLQkJCWRldl9lcnIoZGV2LCAiZmFp bGVkIHRvIGRlYXNzZXJ0IHJlc2V0OiAlZFxuIiwgZXJyKTsKLQkJCXJldHVybiBlcnI7Ci0JCX0K LQl9Ci0KLQlyZXR1cm4gMDsKLX0KLSNlbmRpZgotCi1zdGF0aWMgY29uc3Qgc3RydWN0IGRldl9w bV9vcHMgdGVncmFfZGNfcG1fb3BzID0gewotCVNFVF9SVU5USU1FX1BNX09QUyh0ZWdyYV9kY19z dXNwZW5kLCB0ZWdyYV9kY19yZXN1bWUsIE5VTEwpCi19OwotCiBzdHJ1Y3QgcGxhdGZvcm1fZHJp dmVyIHRlZ3JhX2RjX2RyaXZlciA9IHsKIAkuZHJpdmVyID0gewogCQkubmFtZSA9ICJ0ZWdyYS1k YyIsCiAJCS5vZl9tYXRjaF90YWJsZSA9IHRlZ3JhX2RjX29mX21hdGNoLAotCQkucG0gPSAmdGVn cmFfZGNfcG1fb3BzLAogCX0sCiAJLnByb2JlID0gdGVncmFfZGNfcHJvYmUsCiAJLnJlbW92ZSA9 IHRlZ3JhX2RjX3JlbW92ZSwKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS90ZWdyYS9kcGF1 eC5jIGIvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL2RwYXV4LmMKaW5kZXggNjIyY2RmMWFkMjQ2Li43 ZGZiNTBmNjUwNjcgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2RybS90ZWdyYS9kcGF1eC5jCisr KyBiL2RyaXZlcnMvZ3B1L2RybS90ZWdyYS9kcGF1eC5jCkBAIC01ODgsNyArNTg4LDcgQEAgc3Rh dGljIGludCB0ZWdyYV9kcGF1eF9yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikK IAkvKiBtYWtlIHN1cmUgcGFkcyBhcmUgcG93ZXJlZCBkb3duIHdoZW4gbm90IGluIHVzZSAqLwog CXRlZ3JhX2RwYXV4X3BhZF9wb3dlcl9kb3duKGRwYXV4KTsKIAotCXBtX3J1bnRpbWVfcHV0KCZw ZGV2LT5kZXYpOworCXBtX3J1bnRpbWVfcHV0X3N5bmMoJnBkZXYtPmRldik7CiAJcG1fcnVudGlt ZV9kaXNhYmxlKCZwZGV2LT5kZXYpOwogCiAJZHJtX2RwX2F1eF91bnJlZ2lzdGVyKCZkcGF1eC0+ YXV4KTsKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS90ZWdyYS9kcm0uaCBiL2RyaXZlcnMv Z3B1L2RybS90ZWdyYS9kcm0uaAppbmRleCBkOTQxNTUzZjdhM2QuLmVkOTliNjdkZWIyOSAxMDA2 NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL2RybS5oCisrKyBiL2RyaXZlcnMvZ3B1L2Ry bS90ZWdyYS9kcm0uaApAQCAtMTQ0LDYgKzE0NCw4IEBAIGludCB0ZWdyYV9vdXRwdXRfaW5pdChz dHJ1Y3QgZHJtX2RldmljZSAqZHJtLCBzdHJ1Y3QgdGVncmFfb3V0cHV0ICpvdXRwdXQpOwogdm9p ZCB0ZWdyYV9vdXRwdXRfZXhpdChzdHJ1Y3QgdGVncmFfb3V0cHV0ICpvdXRwdXQpOwogdm9pZCB0 ZWdyYV9vdXRwdXRfZmluZF9wb3NzaWJsZV9jcnRjcyhzdHJ1Y3QgdGVncmFfb3V0cHV0ICpvdXRw dXQsCiAJCQkJICAgICAgc3RydWN0IGRybV9kZXZpY2UgKmRybSk7CitpbnQgdGVncmFfb3V0cHV0 X3N1c3BlbmQoc3RydWN0IHRlZ3JhX291dHB1dCAqb3V0cHV0KTsKK2ludCB0ZWdyYV9vdXRwdXRf cmVzdW1lKHN0cnVjdCB0ZWdyYV9vdXRwdXQgKm91dHB1dCk7CiAKIGludCB0ZWdyYV9vdXRwdXRf Y29ubmVjdG9yX2dldF9tb2RlcyhzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29ubmVjdG9yKTsKIGVu dW0gZHJtX2Nvbm5lY3Rvcl9zdGF0dXMKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS90ZWdy YS9kc2kuYyBiL2RyaXZlcnMvZ3B1L2RybS90ZWdyYS9kc2kuYwppbmRleCBlYzQ3NWQwMjJmYTAu Ljg4YjlkNjRjNzdiZiAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL2RzaS5jCisr KyBiL2RyaXZlcnMvZ3B1L2RybS90ZWdyYS9kc2kuYwpAQCAtODQwLDcgKzg0MCw5IEBAIHN0YXRp YyB2b2lkIHRlZ3JhX2RzaV91bnByZXBhcmUoc3RydWN0IHRlZ3JhX2RzaSAqZHNpKQogCQlkZXZf ZXJyKGRzaS0+ZGV2LCAiZmFpbGVkIHRvIGRpc2FibGUgTUlQSSBjYWxpYnJhdGlvbjogJWRcbiIs CiAJCQllcnIpOwogCi0JcG1fcnVudGltZV9wdXQoZHNpLT5kZXYpOworCWVyciA9IGhvc3QxeF9j bGllbnRfc3VzcGVuZCgmZHNpLT5jbGllbnQpOworCWlmIChlcnIgPCAwKQorCQlkZXZfZXJyKGRz aS0+ZGV2LCAiZmFpbGVkIHRvIHN1c3BlbmQ6ICVkXG4iLCBlcnIpOwogfQogCiBzdGF0aWMgdm9p ZCB0ZWdyYV9kc2lfZW5jb2Rlcl9kaXNhYmxlKHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlcikK QEAgLTg4MiwxMSArODg0LDE1IEBAIHN0YXRpYyB2b2lkIHRlZ3JhX2RzaV9lbmNvZGVyX2Rpc2Fi bGUoc3RydWN0IGRybV9lbmNvZGVyICplbmNvZGVyKQogCXRlZ3JhX2RzaV91bnByZXBhcmUoZHNp KTsKIH0KIAotc3RhdGljIHZvaWQgdGVncmFfZHNpX3ByZXBhcmUoc3RydWN0IHRlZ3JhX2RzaSAq ZHNpKQorc3RhdGljIGludCB0ZWdyYV9kc2lfcHJlcGFyZShzdHJ1Y3QgdGVncmFfZHNpICpkc2kp CiB7CiAJaW50IGVycjsKIAotCXBtX3J1bnRpbWVfZ2V0X3N5bmMoZHNpLT5kZXYpOworCWVyciA9 IGhvc3QxeF9jbGllbnRfcmVzdW1lKCZkc2ktPmNsaWVudCk7CisJaWYgKGVyciA8IDApIHsKKwkJ ZGV2X2Vycihkc2ktPmRldiwgImZhaWxlZCB0byByZXN1bWU6ICVkXG4iLCBlcnIpOworCQlyZXR1 cm4gZXJyOworCX0KIAogCWVyciA9IHRlZ3JhX21pcGlfZW5hYmxlKGRzaS0+bWlwaSk7CiAJaWYg KGVyciA8IDApCkBAIC04OTksNiArOTA1LDggQEAgc3RhdGljIHZvaWQgdGVncmFfZHNpX3ByZXBh cmUoc3RydWN0IHRlZ3JhX2RzaSAqZHNpKQogCiAJaWYgKGRzaS0+c2xhdmUpCiAJCXRlZ3JhX2Rz aV9wcmVwYXJlKGRzaS0+c2xhdmUpOworCisJcmV0dXJuIDA7CiB9CiAKIHN0YXRpYyB2b2lkIHRl Z3JhX2RzaV9lbmNvZGVyX2VuYWJsZShzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIpCkBAIC05 MDksOCArOTE3LDEzIEBAIHN0YXRpYyB2b2lkIHRlZ3JhX2RzaV9lbmNvZGVyX2VuYWJsZShzdHJ1 Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIpCiAJc3RydWN0IHRlZ3JhX2RzaSAqZHNpID0gdG9fZHNp KG91dHB1dCk7CiAJc3RydWN0IHRlZ3JhX2RzaV9zdGF0ZSAqc3RhdGU7CiAJdTMyIHZhbHVlOwor CWludCBlcnI7CiAKLQl0ZWdyYV9kc2lfcHJlcGFyZShkc2kpOworCWVyciA9IHRlZ3JhX2RzaV9w cmVwYXJlKGRzaSk7CisJaWYgKGVyciA8IDApIHsKKwkJZGV2X2Vycihkc2ktPmRldiwgImZhaWxl ZCB0byBwcmVwYXJlOiAlZFxuIiwgZXJyKTsKKwkJcmV0dXJuOworCX0KIAogCXN0YXRlID0gdGVn cmFfZHNpX2dldF9zdGF0ZShkc2kpOwogCkBAIC0xMDc1LDkgKzEwODgsODkgQEAgc3RhdGljIGlu dCB0ZWdyYV9kc2lfZXhpdChzdHJ1Y3QgaG9zdDF4X2NsaWVudCAqY2xpZW50KQogCXJldHVybiAw OwogfQogCitzdGF0aWMgaW50IHRlZ3JhX2RzaV9ydW50aW1lX3N1c3BlbmQoc3RydWN0IGhvc3Qx eF9jbGllbnQgKmNsaWVudCkKK3sKKwlzdHJ1Y3QgdGVncmFfZHNpICpkc2kgPSBob3N0MXhfY2xp ZW50X3RvX2RzaShjbGllbnQpOworCXN0cnVjdCBkZXZpY2UgKmRldiA9IGNsaWVudC0+ZGV2Owor CWludCBlcnI7CisKKwlpZiAoZHNpLT5yc3QpIHsKKwkJZXJyID0gcmVzZXRfY29udHJvbF9hc3Nl cnQoZHNpLT5yc3QpOworCQlpZiAoZXJyIDwgMCkgeworCQkJZGV2X2VycihkZXYsICJmYWlsZWQg dG8gYXNzZXJ0IHJlc2V0OiAlZFxuIiwgZXJyKTsKKwkJCXJldHVybiBlcnI7CisJCX0KKwl9CisK Kwl1c2xlZXBfcmFuZ2UoMTAwMCwgMjAwMCk7CisKKwljbGtfZGlzYWJsZV91bnByZXBhcmUoZHNp LT5jbGtfbHApOworCWNsa19kaXNhYmxlX3VucHJlcGFyZShkc2ktPmNsayk7CisKKwlyZWd1bGF0 b3JfZGlzYWJsZShkc2ktPnZkZCk7CisJcG1fcnVudGltZV9wdXRfc3luYyhkZXYpOworCisJcmV0 dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgdGVncmFfZHNpX3J1bnRpbWVfcmVzdW1lKHN0cnVjdCBo b3N0MXhfY2xpZW50ICpjbGllbnQpCit7CisJc3RydWN0IHRlZ3JhX2RzaSAqZHNpID0gaG9zdDF4 X2NsaWVudF90b19kc2koY2xpZW50KTsKKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSBjbGllbnQtPmRl djsKKwlpbnQgZXJyOworCisJZXJyID0gcG1fcnVudGltZV9nZXRfc3luYyhkZXYpOworCWlmIChl cnIgPCAwKSB7CisJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGdldCBydW50aW1lIFBNOiAlZFxu IiwgZXJyKTsKKwkJcmV0dXJuIGVycjsKKwl9CisKKwllcnIgPSByZWd1bGF0b3JfZW5hYmxlKGRz aS0+dmRkKTsKKwlpZiAoZXJyIDwgMCkgeworCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBlbmFi bGUgVkREIHN1cHBseTogJWRcbiIsIGVycik7CisJCWdvdG8gcHV0X3JwbTsKKwl9CisKKwllcnIg PSBjbGtfcHJlcGFyZV9lbmFibGUoZHNpLT5jbGspOworCWlmIChlcnIgPCAwKSB7CisJCWRldl9l cnIoZGV2LCAiY2Fubm90IGVuYWJsZSBEU0kgY2xvY2s6ICVkXG4iLCBlcnIpOworCQlnb3RvIGRp c2FibGVfdmRkOworCX0KKworCWVyciA9IGNsa19wcmVwYXJlX2VuYWJsZShkc2ktPmNsa19scCk7 CisJaWYgKGVyciA8IDApIHsKKwkJZGV2X2VycihkZXYsICJjYW5ub3QgZW5hYmxlIGxvdy1wb3dl ciBjbG9jazogJWRcbiIsIGVycik7CisJCWdvdG8gZGlzYWJsZV9jbGs7CisJfQorCisJdXNsZWVw X3JhbmdlKDEwMDAsIDIwMDApOworCisJaWYgKGRzaS0+cnN0KSB7CisJCWVyciA9IHJlc2V0X2Nv bnRyb2xfZGVhc3NlcnQoZHNpLT5yc3QpOworCQlpZiAoZXJyIDwgMCkgeworCQkJZGV2X2Vycihk ZXYsICJjYW5ub3QgYXNzZXJ0IHJlc2V0OiAlZFxuIiwgZXJyKTsKKwkJCWdvdG8gZGlzYWJsZV9j bGtfbHA7CisJCX0KKwl9CisKKwlyZXR1cm4gMDsKKworZGlzYWJsZV9jbGtfbHA6CisJY2xrX2Rp c2FibGVfdW5wcmVwYXJlKGRzaS0+Y2xrX2xwKTsKK2Rpc2FibGVfY2xrOgorCWNsa19kaXNhYmxl X3VucHJlcGFyZShkc2ktPmNsayk7CitkaXNhYmxlX3ZkZDoKKwlyZWd1bGF0b3JfZGlzYWJsZShk c2ktPnZkZCk7CitwdXRfcnBtOgorCXBtX3J1bnRpbWVfcHV0X3N5bmMoZGV2KTsKKwlyZXR1cm4g ZXJyOworfQorCiBzdGF0aWMgY29uc3Qgc3RydWN0IGhvc3QxeF9jbGllbnRfb3BzIGRzaV9jbGll bnRfb3BzID0gewogCS5pbml0ID0gdGVncmFfZHNpX2luaXQsCiAJLmV4aXQgPSB0ZWdyYV9kc2lf ZXhpdCwKKwkuc3VzcGVuZCA9IHRlZ3JhX2RzaV9ydW50aW1lX3N1c3BlbmQsCisJLnJlc3VtZSA9 IHRlZ3JhX2RzaV9ydW50aW1lX3Jlc3VtZSwKIH07CiAKIHN0YXRpYyBpbnQgdGVncmFfZHNpX3Nl dHVwX2Nsb2NrcyhzdHJ1Y3QgdGVncmFfZHNpICpkc2kpCkBAIC0xNTk2LDc5ICsxNjg5LDYgQEAg c3RhdGljIGludCB0ZWdyYV9kc2lfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYp CiAJcmV0dXJuIDA7CiB9CiAKLSNpZmRlZiBDT05GSUdfUE0KLXN0YXRpYyBpbnQgdGVncmFfZHNp X3N1c3BlbmQoc3RydWN0IGRldmljZSAqZGV2KQotewotCXN0cnVjdCB0ZWdyYV9kc2kgKmRzaSA9 IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwotCWludCBlcnI7Ci0KLQlpZiAoZHNpLT5yc3QpIHsKLQkJ ZXJyID0gcmVzZXRfY29udHJvbF9hc3NlcnQoZHNpLT5yc3QpOwotCQlpZiAoZXJyIDwgMCkgewot CQkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gYXNzZXJ0IHJlc2V0OiAlZFxuIiwgZXJyKTsKLQkJ CXJldHVybiBlcnI7Ci0JCX0KLQl9Ci0KLQl1c2xlZXBfcmFuZ2UoMTAwMCwgMjAwMCk7Ci0KLQlj bGtfZGlzYWJsZV91bnByZXBhcmUoZHNpLT5jbGtfbHApOwotCWNsa19kaXNhYmxlX3VucHJlcGFy ZShkc2ktPmNsayk7Ci0KLQlyZWd1bGF0b3JfZGlzYWJsZShkc2ktPnZkZCk7Ci0KLQlyZXR1cm4g MDsKLX0KLQotc3RhdGljIGludCB0ZWdyYV9kc2lfcmVzdW1lKHN0cnVjdCBkZXZpY2UgKmRldikK LXsKLQlzdHJ1Y3QgdGVncmFfZHNpICpkc2kgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKLQlpbnQg ZXJyOwotCi0JZXJyID0gcmVndWxhdG9yX2VuYWJsZShkc2ktPnZkZCk7Ci0JaWYgKGVyciA8IDAp IHsKLQkJZGV2X2Vycihkc2ktPmRldiwgImZhaWxlZCB0byBlbmFibGUgVkREIHN1cHBseTogJWRc biIsIGVycik7Ci0JCXJldHVybiBlcnI7Ci0JfQotCi0JZXJyID0gY2xrX3ByZXBhcmVfZW5hYmxl KGRzaS0+Y2xrKTsKLQlpZiAoZXJyIDwgMCkgewotCQlkZXZfZXJyKGRldiwgImNhbm5vdCBlbmFi bGUgRFNJIGNsb2NrOiAlZFxuIiwgZXJyKTsKLQkJZ290byBkaXNhYmxlX3ZkZDsKLQl9Ci0KLQll cnIgPSBjbGtfcHJlcGFyZV9lbmFibGUoZHNpLT5jbGtfbHApOwotCWlmIChlcnIgPCAwKSB7Ci0J CWRldl9lcnIoZGV2LCAiY2Fubm90IGVuYWJsZSBsb3ctcG93ZXIgY2xvY2s6ICVkXG4iLCBlcnIp OwotCQlnb3RvIGRpc2FibGVfY2xrOwotCX0KLQotCXVzbGVlcF9yYW5nZSgxMDAwLCAyMDAwKTsK LQotCWlmIChkc2ktPnJzdCkgewotCQllcnIgPSByZXNldF9jb250cm9sX2RlYXNzZXJ0KGRzaS0+ cnN0KTsKLQkJaWYgKGVyciA8IDApIHsKLQkJCWRldl9lcnIoZGV2LCAiY2Fubm90IGFzc2VydCBy ZXNldDogJWRcbiIsIGVycik7Ci0JCQlnb3RvIGRpc2FibGVfY2xrX2xwOwotCQl9Ci0JfQotCi0J cmV0dXJuIDA7Ci0KLWRpc2FibGVfY2xrX2xwOgotCWNsa19kaXNhYmxlX3VucHJlcGFyZShkc2kt PmNsa19scCk7Ci1kaXNhYmxlX2NsazoKLQljbGtfZGlzYWJsZV91bnByZXBhcmUoZHNpLT5jbGsp OwotZGlzYWJsZV92ZGQ6Ci0JcmVndWxhdG9yX2Rpc2FibGUoZHNpLT52ZGQpOwotCXJldHVybiBl cnI7Ci19Ci0jZW5kaWYKLQotc3RhdGljIGNvbnN0IHN0cnVjdCBkZXZfcG1fb3BzIHRlZ3JhX2Rz aV9wbV9vcHMgPSB7Ci0JU0VUX1JVTlRJTUVfUE1fT1BTKHRlZ3JhX2RzaV9zdXNwZW5kLCB0ZWdy YV9kc2lfcmVzdW1lLCBOVUxMKQotfTsKLQogc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZpY2Vf aWQgdGVncmFfZHNpX29mX21hdGNoW10gPSB7CiAJeyAuY29tcGF0aWJsZSA9ICJudmlkaWEsdGVn cmEyMTAtZHNpIiwgfSwKIAl7IC5jb21wYXRpYmxlID0gIm52aWRpYSx0ZWdyYTEzMi1kc2kiLCB9 LApAQCAtMTY4Miw3ICsxNzAyLDYgQEAgc3RydWN0IHBsYXRmb3JtX2RyaXZlciB0ZWdyYV9kc2lf ZHJpdmVyID0gewogCS5kcml2ZXIgPSB7CiAJCS5uYW1lID0gInRlZ3JhLWRzaSIsCiAJCS5vZl9t YXRjaF90YWJsZSA9IHRlZ3JhX2RzaV9vZl9tYXRjaCwKLQkJLnBtID0gJnRlZ3JhX2RzaV9wbV9v cHMsCiAJfSwKIAkucHJvYmUgPSB0ZWdyYV9kc2lfcHJvYmUsCiAJLnJlbW92ZSA9IHRlZ3JhX2Rz aV9yZW1vdmUsCmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vdGVncmEvaGRtaS5jIGIvZHJp dmVycy9ncHUvZHJtL3RlZ3JhL2hkbWkuYwppbmRleCAzOGJmMWQxNjA5NWYuLmNiNTA0ZWM4ZjI4 NCAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL2hkbWkuYworKysgYi9kcml2ZXJz L2dwdS9kcm0vdGVncmEvaGRtaS5jCkBAIC0xMTQ2LDYgKzExNDYsNyBAQCBzdGF0aWMgdm9pZCB0 ZWdyYV9oZG1pX2VuY29kZXJfZGlzYWJsZShzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIpCiAJ c3RydWN0IHRlZ3JhX2RjICpkYyA9IHRvX3RlZ3JhX2RjKGVuY29kZXItPmNydGMpOwogCXN0cnVj dCB0ZWdyYV9oZG1pICpoZG1pID0gdG9faGRtaShvdXRwdXQpOwogCXUzMiB2YWx1ZTsKKwlpbnQg ZXJyOwogCiAJLyoKIAkgKiBUaGUgZm9sbG93aW5nIGFjY2Vzc2VzIHJlZ2lzdGVycyBvZiB0aGUg ZGlzcGxheSBjb250cm9sbGVyLCBzbyBtYWtlCkBAIC0xMTcxLDcgKzExNzIsOSBAQCBzdGF0aWMg dm9pZCB0ZWdyYV9oZG1pX2VuY29kZXJfZGlzYWJsZShzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29k ZXIpCiAJdGVncmFfaGRtaV93cml0ZWwoaGRtaSwgMCwgSERNSV9OVl9QRElTUF9JTlRfRU5BQkxF KTsKIAl0ZWdyYV9oZG1pX3dyaXRlbChoZG1pLCAwLCBIRE1JX05WX1BESVNQX0lOVF9NQVNLKTsK IAotCXBtX3J1bnRpbWVfcHV0KGhkbWktPmRldik7CisJZXJyID0gaG9zdDF4X2NsaWVudF9zdXNw ZW5kKCZoZG1pLT5jbGllbnQpOworCWlmIChlcnIgPCAwKQorCQlkZXZfZXJyKGhkbWktPmRldiwg ImZhaWxlZCB0byBzdXNwZW5kOiAlZFxuIiwgZXJyKTsKIH0KIAogc3RhdGljIHZvaWQgdGVncmFf aGRtaV9lbmNvZGVyX2VuYWJsZShzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIpCkBAIC0xMTg2 LDcgKzExODksMTEgQEAgc3RhdGljIHZvaWQgdGVncmFfaGRtaV9lbmNvZGVyX2VuYWJsZShzdHJ1 Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIpCiAJdTMyIHZhbHVlOwogCWludCBlcnI7CiAKLQlwbV9y dW50aW1lX2dldF9zeW5jKGhkbWktPmRldik7CisJZXJyID0gaG9zdDF4X2NsaWVudF9yZXN1bWUo JmhkbWktPmNsaWVudCk7CisJaWYgKGVyciA8IDApIHsKKwkJZGV2X2VycihoZG1pLT5kZXYsICJm YWlsZWQgdG8gcmVzdW1lOiAlZFxuIiwgZXJyKTsKKwkJcmV0dXJuOworCX0KIAogCS8qCiAJICog RW5hYmxlIGFuZCB1bm1hc2sgdGhlIEhEQSBjb2RlYyBTQ1JBVENIMCByZWdpc3RlciBpbnRlcnJ1 cHQuIFRoaXMKQEAgLTE0ODksOSArMTQ5Niw2NiBAQCBzdGF0aWMgaW50IHRlZ3JhX2hkbWlfZXhp dChzdHJ1Y3QgaG9zdDF4X2NsaWVudCAqY2xpZW50KQogCXJldHVybiAwOwogfQogCitzdGF0aWMg aW50IHRlZ3JhX2hkbWlfcnVudGltZV9zdXNwZW5kKHN0cnVjdCBob3N0MXhfY2xpZW50ICpjbGll bnQpCit7CisJc3RydWN0IHRlZ3JhX2hkbWkgKmhkbWkgPSBob3N0MXhfY2xpZW50X3RvX2hkbWko Y2xpZW50KTsKKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSBjbGllbnQtPmRldjsKKwlpbnQgZXJyOwor CisJZXJyID0gcmVzZXRfY29udHJvbF9hc3NlcnQoaGRtaS0+cnN0KTsKKwlpZiAoZXJyIDwgMCkg eworCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBhc3NlcnQgcmVzZXQ6ICVkXG4iLCBlcnIpOwor CQlyZXR1cm4gZXJyOworCX0KKworCXVzbGVlcF9yYW5nZSgxMDAwLCAyMDAwKTsKKworCWNsa19k aXNhYmxlX3VucHJlcGFyZShoZG1pLT5jbGspOworCXBtX3J1bnRpbWVfcHV0X3N5bmMoZGV2KTsK KworCXJldHVybiAwOworfQorCitzdGF0aWMgaW50IHRlZ3JhX2hkbWlfcnVudGltZV9yZXN1bWUo c3RydWN0IGhvc3QxeF9jbGllbnQgKmNsaWVudCkKK3sKKwlzdHJ1Y3QgdGVncmFfaGRtaSAqaGRt aSA9IGhvc3QxeF9jbGllbnRfdG9faGRtaShjbGllbnQpOworCXN0cnVjdCBkZXZpY2UgKmRldiA9 IGNsaWVudC0+ZGV2OworCWludCBlcnI7CisKKwllcnIgPSBwbV9ydW50aW1lX2dldF9zeW5jKGRl dik7CisJaWYgKGVyciA8IDApIHsKKwkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gZ2V0IHJ1bnRp bWUgUE06ICVkXG4iLCBlcnIpOworCQlyZXR1cm4gZXJyOworCX0KKworCWVyciA9IGNsa19wcmVw YXJlX2VuYWJsZShoZG1pLT5jbGspOworCWlmIChlcnIgPCAwKSB7CisJCWRldl9lcnIoZGV2LCAi ZmFpbGVkIHRvIGVuYWJsZSBjbG9jazogJWRcbiIsIGVycik7CisJCWdvdG8gcHV0X3JwbTsKKwl9 CisKKwl1c2xlZXBfcmFuZ2UoMTAwMCwgMjAwMCk7CisKKwllcnIgPSByZXNldF9jb250cm9sX2Rl YXNzZXJ0KGhkbWktPnJzdCk7CisJaWYgKGVyciA8IDApIHsKKwkJZGV2X2VycihkZXYsICJmYWls ZWQgdG8gZGVhc3NlcnQgcmVzZXQ6ICVkXG4iLCBlcnIpOworCQlnb3RvIGRpc2FibGVfY2xrOwor CX0KKworCXJldHVybiAwOworCitkaXNhYmxlX2NsazoKKwljbGtfZGlzYWJsZV91bnByZXBhcmUo aGRtaS0+Y2xrKTsKK3B1dF9ycG06CisJcG1fcnVudGltZV9wdXRfc3luYyhkZXYpOworCXJldHVy biBlcnI7Cit9CisKIHN0YXRpYyBjb25zdCBzdHJ1Y3QgaG9zdDF4X2NsaWVudF9vcHMgaGRtaV9j bGllbnRfb3BzID0gewogCS5pbml0ID0gdGVncmFfaGRtaV9pbml0LAogCS5leGl0ID0gdGVncmFf aGRtaV9leGl0LAorCS5zdXNwZW5kID0gdGVncmFfaGRtaV9ydW50aW1lX3N1c3BlbmQsCisJLnJl c3VtZSA9IHRlZ3JhX2hkbWlfcnVudGltZV9yZXN1bWUsCiB9OwogCiBzdGF0aWMgY29uc3Qgc3Ry dWN0IHRlZ3JhX2hkbWlfY29uZmlnIHRlZ3JhMjBfaGRtaV9jb25maWcgPSB7CkBAIC0xNjk5LDU4 ICsxNzYzLDEwIEBAIHN0YXRpYyBpbnQgdGVncmFfaGRtaV9yZW1vdmUoc3RydWN0IHBsYXRmb3Jt X2RldmljZSAqcGRldikKIAlyZXR1cm4gMDsKIH0KIAotI2lmZGVmIENPTkZJR19QTQotc3RhdGlj IGludCB0ZWdyYV9oZG1pX3N1c3BlbmQoc3RydWN0IGRldmljZSAqZGV2KQotewotCXN0cnVjdCB0 ZWdyYV9oZG1pICpoZG1pID0gZGV2X2dldF9kcnZkYXRhKGRldik7Ci0JaW50IGVycjsKLQotCWVy ciA9IHJlc2V0X2NvbnRyb2xfYXNzZXJ0KGhkbWktPnJzdCk7Ci0JaWYgKGVyciA8IDApIHsKLQkJ ZGV2X2VycihkZXYsICJmYWlsZWQgdG8gYXNzZXJ0IHJlc2V0OiAlZFxuIiwgZXJyKTsKLQkJcmV0 dXJuIGVycjsKLQl9Ci0KLQl1c2xlZXBfcmFuZ2UoMTAwMCwgMjAwMCk7Ci0KLQljbGtfZGlzYWJs ZV91bnByZXBhcmUoaGRtaS0+Y2xrKTsKLQotCXJldHVybiAwOwotfQotCi1zdGF0aWMgaW50IHRl Z3JhX2hkbWlfcmVzdW1lKHN0cnVjdCBkZXZpY2UgKmRldikKLXsKLQlzdHJ1Y3QgdGVncmFfaGRt aSAqaGRtaSA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwotCWludCBlcnI7Ci0KLQllcnIgPSBjbGtf cHJlcGFyZV9lbmFibGUoaGRtaS0+Y2xrKTsKLQlpZiAoZXJyIDwgMCkgewotCQlkZXZfZXJyKGRl diwgImZhaWxlZCB0byBlbmFibGUgY2xvY2s6ICVkXG4iLCBlcnIpOwotCQlyZXR1cm4gZXJyOwot CX0KLQotCXVzbGVlcF9yYW5nZSgxMDAwLCAyMDAwKTsKLQotCWVyciA9IHJlc2V0X2NvbnRyb2xf ZGVhc3NlcnQoaGRtaS0+cnN0KTsKLQlpZiAoZXJyIDwgMCkgewotCQlkZXZfZXJyKGRldiwgImZh aWxlZCB0byBkZWFzc2VydCByZXNldDogJWRcbiIsIGVycik7Ci0JCWNsa19kaXNhYmxlX3VucHJl cGFyZShoZG1pLT5jbGspOwotCQlyZXR1cm4gZXJyOwotCX0KLQotCXJldHVybiAwOwotfQotI2Vu ZGlmCi0KLXN0YXRpYyBjb25zdCBzdHJ1Y3QgZGV2X3BtX29wcyB0ZWdyYV9oZG1pX3BtX29wcyA9 IHsKLQlTRVRfUlVOVElNRV9QTV9PUFModGVncmFfaGRtaV9zdXNwZW5kLCB0ZWdyYV9oZG1pX3Jl c3VtZSwgTlVMTCkKLX07Ci0KIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgdGVncmFfaGRtaV9kcml2 ZXIgPSB7CiAJLmRyaXZlciA9IHsKIAkJLm5hbWUgPSAidGVncmEtaGRtaSIsCiAJCS5vZl9tYXRj aF90YWJsZSA9IHRlZ3JhX2hkbWlfb2ZfbWF0Y2gsCi0JCS5wbSA9ICZ0ZWdyYV9oZG1pX3BtX29w cywKIAl9LAogCS5wcm9iZSA9IHRlZ3JhX2hkbWlfcHJvYmUsCiAJLnJlbW92ZSA9IHRlZ3JhX2hk bWlfcmVtb3ZlLApkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL2h1Yi5jIGIvZHJp dmVycy9ncHUvZHJtL3RlZ3JhL2h1Yi5jCmluZGV4IDVjNzU0NWVlNWE1Yi4uNzNlNmZlOWI4MzNk IDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vdGVncmEvaHViLmMKKysrIGIvZHJpdmVycy9n cHUvZHJtL3RlZ3JhL2h1Yi5jCkBAIC0xMDUsMTcgKzEwNSwyNSBAQCBzdGF0aWMgaW5saW5lIHZv aWQgdGVncmFfcGxhbmVfd3JpdGVsKHN0cnVjdCB0ZWdyYV9wbGFuZSAqcGxhbmUsIHUzMiB2YWx1 ZSwKIAogc3RhdGljIGludCB0ZWdyYV93aW5kb3dncm91cF9lbmFibGUoc3RydWN0IHRlZ3JhX3dp bmRvd2dyb3VwICp3Z3JwKQogeworCWludCBlcnIgPSAwOworCiAJbXV0ZXhfbG9jaygmd2dycC0+ bG9jayk7CiAKIAlpZiAod2dycC0+dXNlY291bnQgPT0gMCkgewotCQlwbV9ydW50aW1lX2dldF9z eW5jKHdncnAtPnBhcmVudCk7CisJCWVyciA9IGhvc3QxeF9jbGllbnRfcmVzdW1lKHdncnAtPnBh cmVudCk7CisJCWlmIChlcnIgPCAwKSB7CisJCQlkZXZfZXJyKHdncnAtPnBhcmVudC0+ZGV2LCAi ZmFpbGVkIHRvIHJlc3VtZTogJWRcbiIsIGVycik7CisJCQlnb3RvIHVubG9jazsKKwkJfQorCiAJ CXJlc2V0X2NvbnRyb2xfZGVhc3NlcnQod2dycC0+cnN0KTsKIAl9CiAKIAl3Z3JwLT51c2Vjb3Vu dCsrOwotCW11dGV4X3VubG9jaygmd2dycC0+bG9jayk7CiAKLQlyZXR1cm4gMDsKK3VubG9jazoK KwltdXRleF91bmxvY2soJndncnAtPmxvY2spOworCXJldHVybiBlcnI7CiB9CiAKIHN0YXRpYyB2 b2lkIHRlZ3JhX3dpbmRvd2dyb3VwX2Rpc2FibGUoc3RydWN0IHRlZ3JhX3dpbmRvd2dyb3VwICp3 Z3JwKQpAQCAtMTMxLDcgKzEzOSw3IEBAIHN0YXRpYyB2b2lkIHRlZ3JhX3dpbmRvd2dyb3VwX2Rp c2FibGUoc3RydWN0IHRlZ3JhX3dpbmRvd2dyb3VwICp3Z3JwKQogCQkJICAgICAgIHdncnAtPmlu ZGV4KTsKIAkJfQogCi0JCXBtX3J1bnRpbWVfcHV0KHdncnAtPnBhcmVudCk7CisJCWhvc3QxeF9j bGllbnRfc3VzcGVuZCh3Z3JwLT5wYXJlbnQpOwogCX0KIAogCXdncnAtPnVzZWNvdW50LS07CkBA IC0zODksNiArMzk3LDcgQEAgc3RhdGljIHZvaWQgdGVncmFfc2hhcmVkX3BsYW5lX2F0b21pY19k aXNhYmxlKHN0cnVjdCBkcm1fcGxhbmUgKnBsYW5lLAogCXN0cnVjdCB0ZWdyYV9wbGFuZSAqcCA9 IHRvX3RlZ3JhX3BsYW5lKHBsYW5lKTsKIAlzdHJ1Y3QgdGVncmFfZGMgKmRjOwogCXUzMiB2YWx1 ZTsKKwlpbnQgZXJyOwogCiAJLyogcmllbiBuZSB2YSBwbHVzICovCiAJaWYgKCFvbGRfc3RhdGUg fHwgIW9sZF9zdGF0ZS0+Y3J0YykKQEAgLTM5Niw2ICs0MDUsMTIgQEAgc3RhdGljIHZvaWQgdGVn cmFfc2hhcmVkX3BsYW5lX2F0b21pY19kaXNhYmxlKHN0cnVjdCBkcm1fcGxhbmUgKnBsYW5lLAog CiAJZGMgPSB0b190ZWdyYV9kYyhvbGRfc3RhdGUtPmNydGMpOwogCisJZXJyID0gaG9zdDF4X2Ns aWVudF9yZXN1bWUoJmRjLT5jbGllbnQpOworCWlmIChlcnIgPCAwKSB7CisJCWRldl9lcnIoZGMt PmRldiwgImZhaWxlZCB0byByZXN1bWU6ICVkXG4iLCBlcnIpOworCQlyZXR1cm47CisJfQorCiAJ LyoKIAkgKiBYWFggTGVnYWN5IGhlbHBlcnMgc2VlbSB0byBzb21ldGltZXMgY2FsbCAtPmF0b21p Y19kaXNhYmxlKCkgZXZlbgogCSAqIG9uIHBsYW5lcyB0aGF0IGFyZSBhbHJlYWR5IGRpc2FibGVk LiBNYWtlIHN1cmUgd2UgZmFsbGJhY2sgdG8gdGhlCkBAIC00MDQsMTUgKzQxOSwxMyBAQCBzdGF0 aWMgdm9pZCB0ZWdyYV9zaGFyZWRfcGxhbmVfYXRvbWljX2Rpc2FibGUoc3RydWN0IGRybV9wbGFu ZSAqcGxhbmUsCiAJaWYgKFdBUk5fT04ocC0+ZGMgPT0gTlVMTCkpCiAJCXAtPmRjID0gZGM7CiAK LQlwbV9ydW50aW1lX2dldF9zeW5jKGRjLT5kZXYpOwotCiAJdmFsdWUgPSB0ZWdyYV9wbGFuZV9y ZWFkbChwLCBEQ19XSU5fV0lOX09QVElPTlMpOwogCXZhbHVlICY9IH5XSU5fRU5BQkxFOwogCXRl Z3JhX3BsYW5lX3dyaXRlbChwLCB2YWx1ZSwgRENfV0lOX1dJTl9PUFRJT05TKTsKIAogCXRlZ3Jh X2RjX3JlbW92ZV9zaGFyZWRfcGxhbmUoZGMsIHApOwogCi0JcG1fcnVudGltZV9wdXQoZGMtPmRl dik7CisJaG9zdDF4X2NsaWVudF9zdXNwZW5kKCZkYy0+Y2xpZW50KTsKIH0KIAogc3RhdGljIHZv aWQgdGVncmFfc2hhcmVkX3BsYW5lX2F0b21pY191cGRhdGUoc3RydWN0IGRybV9wbGFuZSAqcGxh bmUsCkBAIC00MjUsNiArNDM4LDcgQEAgc3RhdGljIHZvaWQgdGVncmFfc2hhcmVkX3BsYW5lX2F0 b21pY191cGRhdGUoc3RydWN0IGRybV9wbGFuZSAqcGxhbmUsCiAJc3RydWN0IHRlZ3JhX3BsYW5l ICpwID0gdG9fdGVncmFfcGxhbmUocGxhbmUpOwogCWRtYV9hZGRyX3QgYmFzZTsKIAl1MzIgdmFs dWU7CisJaW50IGVycjsKIAogCS8qIHJpZW4gbmUgdmEgcGx1cyAqLwogCWlmICghcGxhbmUtPnN0 YXRlLT5jcnRjIHx8ICFwbGFuZS0+c3RhdGUtPmZiKQpAQCAtNDM1LDcgKzQ0OSwxMSBAQCBzdGF0 aWMgdm9pZCB0ZWdyYV9zaGFyZWRfcGxhbmVfYXRvbWljX3VwZGF0ZShzdHJ1Y3QgZHJtX3BsYW5l ICpwbGFuZSwKIAkJcmV0dXJuOwogCX0KIAotCXBtX3J1bnRpbWVfZ2V0X3N5bmMoZGMtPmRldik7 CisJZXJyID0gaG9zdDF4X2NsaWVudF9yZXN1bWUoJmRjLT5jbGllbnQpOworCWlmIChlcnIgPCAw KSB7CisJCWRldl9lcnIoZGMtPmRldiwgImZhaWxlZCB0byByZXN1bWU6ICVkXG4iLCBlcnIpOwor CQlyZXR1cm47CisJfQogCiAJdGVncmFfZGNfYXNzaWduX3NoYXJlZF9wbGFuZShkYywgcCk7CiAK QEAgLTUyNSw3ICs1NDMsNyBAQCBzdGF0aWMgdm9pZCB0ZWdyYV9zaGFyZWRfcGxhbmVfYXRvbWlj X3VwZGF0ZShzdHJ1Y3QgZHJtX3BsYW5lICpwbGFuZSwKIAl2YWx1ZSAmPSB+Q09OVFJPTF9DU0Nf RU5BQkxFOwogCXRlZ3JhX3BsYW5lX3dyaXRlbChwLCB2YWx1ZSwgRENfV0lOX1dJTkRPV19TRVRf Q09OVFJPTCk7CiAKLQlwbV9ydW50aW1lX3B1dChkYy0+ZGV2KTsKKwlob3N0MXhfY2xpZW50X3N1 c3BlbmQoJmRjLT5jbGllbnQpOwogfQogCiBzdGF0aWMgY29uc3Qgc3RydWN0IGRybV9wbGFuZV9o ZWxwZXJfZnVuY3MgdGVncmFfc2hhcmVkX3BsYW5lX2hlbHBlcl9mdW5jcyA9IHsKQEAgLTU2MSw3 ICs1NzksNyBAQCBzdHJ1Y3QgZHJtX3BsYW5lICp0ZWdyYV9zaGFyZWRfcGxhbmVfY3JlYXRlKHN0 cnVjdCBkcm1fZGV2aWNlICpkcm0sCiAJcGxhbmUtPmJhc2UuaW5kZXggPSBpbmRleDsKIAogCXBs YW5lLT53Z3JwID0gJmh1Yi0+d2dycHNbd2dycF07Ci0JcGxhbmUtPndncnAtPnBhcmVudCA9IGRj LT5kZXY7CisJcGxhbmUtPndncnAtPnBhcmVudCA9ICZkYy0+Y2xpZW50OwogCiAJcCA9ICZwbGFu ZS0+YmFzZS5iYXNlOwogCkBAIC02NjYsOCArNjg0LDEzIEBAIGludCB0ZWdyYV9kaXNwbGF5X2h1 Yl9hdG9taWNfY2hlY2soc3RydWN0IGRybV9kZXZpY2UgKmRybSwKIHN0YXRpYyB2b2lkIHRlZ3Jh X2Rpc3BsYXlfaHViX3VwZGF0ZShzdHJ1Y3QgdGVncmFfZGMgKmRjKQogewogCXUzMiB2YWx1ZTsK KwlpbnQgZXJyOwogCi0JcG1fcnVudGltZV9nZXRfc3luYyhkYy0+ZGV2KTsKKwllcnIgPSBob3N0 MXhfY2xpZW50X3Jlc3VtZSgmZGMtPmNsaWVudCk7CisJaWYgKGVyciA8IDApIHsKKwkJZGV2X2Vy cihkYy0+ZGV2LCAiZmFpbGVkIHRvIHJlc3VtZTogJWRcbiIsIGVycik7CisJCXJldHVybjsKKwl9 CiAKIAl2YWx1ZSA9IHRlZ3JhX2RjX3JlYWRsKGRjLCBEQ19DTURfSUhVQl9DT01NT05fTUlTQ19D VEwpOwogCXZhbHVlICY9IH5MQVRFTkNZX0VWRU5UOwpAQCAtNjgyLDcgKzcwNSw3IEBAIHN0YXRp YyB2b2lkIHRlZ3JhX2Rpc3BsYXlfaHViX3VwZGF0ZShzdHJ1Y3QgdGVncmFfZGMgKmRjKQogCXRl Z3JhX2RjX3dyaXRlbChkYywgQ09NTU9OX0FDVFJFUSwgRENfQ01EX1NUQVRFX0NPTlRST0wpOwog CXRlZ3JhX2RjX3JlYWRsKGRjLCBEQ19DTURfU1RBVEVfQ09OVFJPTCk7CiAKLQlwbV9ydW50aW1l X3B1dChkYy0+ZGV2KTsKKwlob3N0MXhfY2xpZW50X3N1c3BlbmQoJmRjLT5jbGllbnQpOwogfQog CiB2b2lkIHRlZ3JhX2Rpc3BsYXlfaHViX2F0b21pY19jb21taXQoc3RydWN0IGRybV9kZXZpY2Ug KmRybSwKQEAgLTc0Miw5ICs3NjUsODUgQEAgc3RhdGljIGludCB0ZWdyYV9kaXNwbGF5X2h1Yl9l eGl0KHN0cnVjdCBob3N0MXhfY2xpZW50ICpjbGllbnQpCiAJcmV0dXJuIDA7CiB9CiAKK3N0YXRp YyBpbnQgdGVncmFfZGlzcGxheV9odWJfcnVudGltZV9zdXNwZW5kKHN0cnVjdCBob3N0MXhfY2xp ZW50ICpjbGllbnQpCit7CisJc3RydWN0IHRlZ3JhX2Rpc3BsYXlfaHViICpodWIgPSB0b190ZWdy YV9kaXNwbGF5X2h1YihjbGllbnQpOworCXN0cnVjdCBkZXZpY2UgKmRldiA9IGNsaWVudC0+ZGV2 OworCXVuc2lnbmVkIGludCBpID0gaHViLT5udW1faGVhZHM7CisJaW50IGVycjsKKworCWVyciA9 IHJlc2V0X2NvbnRyb2xfYXNzZXJ0KGh1Yi0+cnN0KTsKKwlpZiAoZXJyIDwgMCkKKwkJcmV0dXJu IGVycjsKKworCXdoaWxlIChpLS0pCisJCWNsa19kaXNhYmxlX3VucHJlcGFyZShodWItPmNsa19o ZWFkc1tpXSk7CisKKwljbGtfZGlzYWJsZV91bnByZXBhcmUoaHViLT5jbGtfaHViKTsKKwljbGtf ZGlzYWJsZV91bnByZXBhcmUoaHViLT5jbGtfZHNjKTsKKwljbGtfZGlzYWJsZV91bnByZXBhcmUo aHViLT5jbGtfZGlzcCk7CisKKwlwbV9ydW50aW1lX3B1dF9zeW5jKGRldik7CisKKwlyZXR1cm4g MDsKK30KKworc3RhdGljIGludCB0ZWdyYV9kaXNwbGF5X2h1Yl9ydW50aW1lX3Jlc3VtZShzdHJ1 Y3QgaG9zdDF4X2NsaWVudCAqY2xpZW50KQoreworCXN0cnVjdCB0ZWdyYV9kaXNwbGF5X2h1YiAq aHViID0gdG9fdGVncmFfZGlzcGxheV9odWIoY2xpZW50KTsKKwlzdHJ1Y3QgZGV2aWNlICpkZXYg PSBjbGllbnQtPmRldjsKKwl1bnNpZ25lZCBpbnQgaTsKKwlpbnQgZXJyOworCisJZXJyID0gcG1f cnVudGltZV9nZXRfc3luYyhkZXYpOworCWlmIChlcnIgPCAwKSB7CisJCWRldl9lcnIoZGV2LCAi ZmFpbGVkIHRvIGdldCBydW50aW1lIFBNOiAlZFxuIiwgZXJyKTsKKwkJcmV0dXJuIGVycjsKKwl9 CisKKwllcnIgPSBjbGtfcHJlcGFyZV9lbmFibGUoaHViLT5jbGtfZGlzcCk7CisJaWYgKGVyciA8 IDApCisJCWdvdG8gcHV0X3JwbTsKKworCWVyciA9IGNsa19wcmVwYXJlX2VuYWJsZShodWItPmNs a19kc2MpOworCWlmIChlcnIgPCAwKQorCQlnb3RvIGRpc2FibGVfZGlzcDsKKworCWVyciA9IGNs a19wcmVwYXJlX2VuYWJsZShodWItPmNsa19odWIpOworCWlmIChlcnIgPCAwKQorCQlnb3RvIGRp c2FibGVfZHNjOworCisJZm9yIChpID0gMDsgaSA8IGh1Yi0+bnVtX2hlYWRzOyBpKyspIHsKKwkJ ZXJyID0gY2xrX3ByZXBhcmVfZW5hYmxlKGh1Yi0+Y2xrX2hlYWRzW2ldKTsKKwkJaWYgKGVyciA8 IDApCisJCQlnb3RvIGRpc2FibGVfaGVhZHM7CisJfQorCisJZXJyID0gcmVzZXRfY29udHJvbF9k ZWFzc2VydChodWItPnJzdCk7CisJaWYgKGVyciA8IDApCisJCWdvdG8gZGlzYWJsZV9oZWFkczsK KworCXJldHVybiAwOworCitkaXNhYmxlX2hlYWRzOgorCXdoaWxlIChpLS0pCisJCWNsa19kaXNh YmxlX3VucHJlcGFyZShodWItPmNsa19oZWFkc1tpXSk7CisKKwljbGtfZGlzYWJsZV91bnByZXBh cmUoaHViLT5jbGtfaHViKTsKK2Rpc2FibGVfZHNjOgorCWNsa19kaXNhYmxlX3VucHJlcGFyZSho dWItPmNsa19kc2MpOworZGlzYWJsZV9kaXNwOgorCWNsa19kaXNhYmxlX3VucHJlcGFyZShodWIt PmNsa19kaXNwKTsKK3B1dF9ycG06CisJcG1fcnVudGltZV9wdXRfc3luYyhkZXYpOworCXJldHVy biBlcnI7Cit9CisKIHN0YXRpYyBjb25zdCBzdHJ1Y3QgaG9zdDF4X2NsaWVudF9vcHMgdGVncmFf ZGlzcGxheV9odWJfb3BzID0gewogCS5pbml0ID0gdGVncmFfZGlzcGxheV9odWJfaW5pdCwKIAku ZXhpdCA9IHRlZ3JhX2Rpc3BsYXlfaHViX2V4aXQsCisJLnN1c3BlbmQgPSB0ZWdyYV9kaXNwbGF5 X2h1Yl9ydW50aW1lX3N1c3BlbmQsCisJLnJlc3VtZSA9IHRlZ3JhX2Rpc3BsYXlfaHViX3J1bnRp bWVfcmVzdW1lLAogfTsKIAogc3RhdGljIGludCB0ZWdyYV9kaXNwbGF5X2h1Yl9wcm9iZShzdHJ1 Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQpAQCAtODYxLDYgKzk2MCw3IEBAIHN0YXRpYyBpbnQg dGVncmFfZGlzcGxheV9odWJfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKIHN0 YXRpYyBpbnQgdGVncmFfZGlzcGxheV9odWJfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2Ug KnBkZXYpCiB7CiAJc3RydWN0IHRlZ3JhX2Rpc3BsYXlfaHViICpodWIgPSBwbGF0Zm9ybV9nZXRf ZHJ2ZGF0YShwZGV2KTsKKwl1bnNpZ25lZCBpbnQgaTsKIAlpbnQgZXJyOwogCiAJZXJyID0gaG9z dDF4X2NsaWVudF91bnJlZ2lzdGVyKCZodWItPmNsaWVudCk7CkBAIC04NjksNzggKzk2OSwxNyBA QCBzdGF0aWMgaW50IHRlZ3JhX2Rpc3BsYXlfaHViX3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2 aWNlICpwZGV2KQogCQkJZXJyKTsKIAl9CiAKLQlwbV9ydW50aW1lX2Rpc2FibGUoJnBkZXYtPmRl dik7Ci0KLQlyZXR1cm4gZXJyOwotfQotCi1zdGF0aWMgaW50IF9fbWF5YmVfdW51c2VkIHRlZ3Jh X2Rpc3BsYXlfaHViX3N1c3BlbmQoc3RydWN0IGRldmljZSAqZGV2KQotewotCXN0cnVjdCB0ZWdy YV9kaXNwbGF5X2h1YiAqaHViID0gZGV2X2dldF9kcnZkYXRhKGRldik7Ci0JdW5zaWduZWQgaW50 IGkgPSBodWItPm51bV9oZWFkczsKLQlpbnQgZXJyOwotCi0JZXJyID0gcmVzZXRfY29udHJvbF9h c3NlcnQoaHViLT5yc3QpOwotCWlmIChlcnIgPCAwKQotCQlyZXR1cm4gZXJyOwotCi0Jd2hpbGUg KGktLSkKLQkJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKGh1Yi0+Y2xrX2hlYWRzW2ldKTsKLQotCWNs a19kaXNhYmxlX3VucHJlcGFyZShodWItPmNsa19odWIpOwotCWNsa19kaXNhYmxlX3VucHJlcGFy ZShodWItPmNsa19kc2MpOwotCWNsa19kaXNhYmxlX3VucHJlcGFyZShodWItPmNsa19kaXNwKTsK LQotCXJldHVybiAwOwotfQotCi1zdGF0aWMgaW50IF9fbWF5YmVfdW51c2VkIHRlZ3JhX2Rpc3Bs YXlfaHViX3Jlc3VtZShzdHJ1Y3QgZGV2aWNlICpkZXYpCi17Ci0Jc3RydWN0IHRlZ3JhX2Rpc3Bs YXlfaHViICpodWIgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKLQl1bnNpZ25lZCBpbnQgaTsKLQlp bnQgZXJyOwotCi0JZXJyID0gY2xrX3ByZXBhcmVfZW5hYmxlKGh1Yi0+Y2xrX2Rpc3ApOwotCWlm IChlcnIgPCAwKQotCQlyZXR1cm4gZXJyOwotCi0JZXJyID0gY2xrX3ByZXBhcmVfZW5hYmxlKGh1 Yi0+Y2xrX2RzYyk7Ci0JaWYgKGVyciA8IDApCi0JCWdvdG8gZGlzYWJsZV9kaXNwOwotCi0JZXJy ID0gY2xrX3ByZXBhcmVfZW5hYmxlKGh1Yi0+Y2xrX2h1Yik7Ci0JaWYgKGVyciA8IDApCi0JCWdv dG8gZGlzYWJsZV9kc2M7CisJZm9yIChpID0gMDsgaSA8IGh1Yi0+c29jLT5udW1fd2dycHM7IGkr KykgeworCQlzdHJ1Y3QgdGVncmFfd2luZG93Z3JvdXAgKndncnAgPSAmaHViLT53Z3Jwc1tpXTsK IAotCWZvciAoaSA9IDA7IGkgPCBodWItPm51bV9oZWFkczsgaSsrKSB7Ci0JCWVyciA9IGNsa19w cmVwYXJlX2VuYWJsZShodWItPmNsa19oZWFkc1tpXSk7Ci0JCWlmIChlcnIgPCAwKQotCQkJZ290 byBkaXNhYmxlX2hlYWRzOworCQltdXRleF9kZXN0cm95KCZ3Z3JwLT5sb2NrKTsKIAl9CiAKLQll cnIgPSByZXNldF9jb250cm9sX2RlYXNzZXJ0KGh1Yi0+cnN0KTsKLQlpZiAoZXJyIDwgMCkKLQkJ Z290byBkaXNhYmxlX2hlYWRzOwotCi0JcmV0dXJuIDA7Ci0KLWRpc2FibGVfaGVhZHM6Ci0Jd2hp bGUgKGktLSkKLQkJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKGh1Yi0+Y2xrX2hlYWRzW2ldKTsKKwlw bV9ydW50aW1lX2Rpc2FibGUoJnBkZXYtPmRldik7CiAKLQljbGtfZGlzYWJsZV91bnByZXBhcmUo aHViLT5jbGtfaHViKTsKLWRpc2FibGVfZHNjOgotCWNsa19kaXNhYmxlX3VucHJlcGFyZShodWIt PmNsa19kc2MpOwotZGlzYWJsZV9kaXNwOgotCWNsa19kaXNhYmxlX3VucHJlcGFyZShodWItPmNs a19kaXNwKTsKIAlyZXR1cm4gZXJyOwogfQogCi1zdGF0aWMgY29uc3Qgc3RydWN0IGRldl9wbV9v cHMgdGVncmFfZGlzcGxheV9odWJfcG1fb3BzID0gewotCVNFVF9SVU5USU1FX1BNX09QUyh0ZWdy YV9kaXNwbGF5X2h1Yl9zdXNwZW5kLAotCQkJICAgdGVncmFfZGlzcGxheV9odWJfcmVzdW1lLCBO VUxMKQotfTsKLQogc3RhdGljIGNvbnN0IHN0cnVjdCB0ZWdyYV9kaXNwbGF5X2h1Yl9zb2MgdGVn cmExODZfZGlzcGxheV9odWIgPSB7CiAJLm51bV93Z3JwcyA9IDYsCiAJLnN1cHBvcnRzX2RzYyA9 IHRydWUsCkBAIC05NjgsNyArMTAwNyw2IEBAIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgdGVncmFf ZGlzcGxheV9odWJfZHJpdmVyID0gewogCS5kcml2ZXIgPSB7CiAJCS5uYW1lID0gInRlZ3JhLWRp c3BsYXktaHViIiwKIAkJLm9mX21hdGNoX3RhYmxlID0gdGVncmFfZGlzcGxheV9odWJfb2ZfbWF0 Y2gsCi0JCS5wbSA9ICZ0ZWdyYV9kaXNwbGF5X2h1Yl9wbV9vcHMsCiAJfSwKIAkucHJvYmUgPSB0 ZWdyYV9kaXNwbGF5X2h1Yl9wcm9iZSwKIAkucmVtb3ZlID0gdGVncmFfZGlzcGxheV9odWJfcmVt b3ZlLApkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL2h1Yi5oIGIvZHJpdmVycy9n cHUvZHJtL3RlZ3JhL2h1Yi5oCmluZGV4IDc2N2E2MGQ5MzEzYy4uM2VmYTFiZTA3ZmY4IDEwMDY0 NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vdGVncmEvaHViLmgKKysrIGIvZHJpdmVycy9ncHUvZHJt L3RlZ3JhL2h1Yi5oCkBAIC0xNyw3ICsxNyw3IEBAIHN0cnVjdCB0ZWdyYV93aW5kb3dncm91cCB7 CiAJc3RydWN0IG11dGV4IGxvY2s7CiAKIAl1bnNpZ25lZCBpbnQgaW5kZXg7Ci0Jc3RydWN0IGRl dmljZSAqcGFyZW50OworCXN0cnVjdCBob3N0MXhfY2xpZW50ICpwYXJlbnQ7CiAJc3RydWN0IHJl c2V0X2NvbnRyb2wgKnJzdDsKIH07CiAKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS90ZWdy YS9zb3IuYyBiL2RyaXZlcnMvZ3B1L2RybS90ZWdyYS9zb3IuYwppbmRleCA5NTZiZjVkNjgwYWQu LjIwMGQ5OWUxN2FmZSAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL3Nvci5jCisr KyBiL2RyaXZlcnMvZ3B1L2RybS90ZWdyYS9zb3IuYwpAQCAtMjI1NSw3ICsyMjU1LDcgQEAgc3Rh dGljIHZvaWQgdGVncmFfc29yX2hkbWlfZGlzYWJsZShzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29k ZXIpCiAJaWYgKGVyciA8IDApCiAJCWRldl9lcnIoc29yLT5kZXYsICJmYWlsZWQgdG8gcG93ZXIg b2ZmIEkvTyBwYWQ6ICVkXG4iLCBlcnIpOwogCi0JcG1fcnVudGltZV9wdXQoc29yLT5kZXYpOwor CWhvc3QxeF9jbGllbnRfc3VzcGVuZCgmc29yLT5jbGllbnQpOwogfQogCiBzdGF0aWMgdm9pZCB0 ZWdyYV9zb3JfaGRtaV9lbmFibGUoc3RydWN0IGRybV9lbmNvZGVyICplbmNvZGVyKQpAQCAtMjI3 Niw3ICsyMjc2LDExIEBAIHN0YXRpYyB2b2lkIHRlZ3JhX3Nvcl9oZG1pX2VuYWJsZShzdHJ1Y3Qg ZHJtX2VuY29kZXIgKmVuY29kZXIpCiAJbW9kZSA9ICZlbmNvZGVyLT5jcnRjLT5zdGF0ZS0+YWRq dXN0ZWRfbW9kZTsKIAlwY2xrID0gbW9kZS0+Y2xvY2sgKiAxMDAwOwogCi0JcG1fcnVudGltZV9n ZXRfc3luYyhzb3ItPmRldik7CisJZXJyID0gaG9zdDF4X2NsaWVudF9yZXN1bWUoJnNvci0+Y2xp ZW50KTsKKwlpZiAoZXJyIDwgMCkgeworCQlkZXZfZXJyKHNvci0+ZGV2LCAiZmFpbGVkIHRvIHJl c3VtZTogJWRcbiIsIGVycik7CisJCXJldHVybjsKKwl9CiAKIAkvKiBzd2l0Y2ggdG8gc2FmZSBw YXJlbnQgY2xvY2sgKi8KIAllcnIgPSB0ZWdyYV9zb3Jfc2V0X3BhcmVudF9jbG9jayhzb3IsIHNv ci0+Y2xrX3NhZmUpOwpAQCAtMjcyMiw3ICsyNzI2LDcgQEAgc3RhdGljIHZvaWQgdGVncmFfc29y X2RwX2Rpc2FibGUoc3RydWN0IGRybV9lbmNvZGVyICplbmNvZGVyKQogCWlmIChvdXRwdXQtPnBh bmVsKQogCQlkcm1fcGFuZWxfdW5wcmVwYXJlKG91dHB1dC0+cGFuZWwpOwogCi0JcG1fcnVudGlt ZV9wdXQoc29yLT5kZXYpOworCWhvc3QxeF9jbGllbnRfc3VzcGVuZCgmc29yLT5jbGllbnQpOwog fQogCiBzdGF0aWMgdm9pZCB0ZWdyYV9zb3JfZHBfZW5hYmxlKHN0cnVjdCBkcm1fZW5jb2RlciAq ZW5jb2RlcikKQEAgLTI3NDIsNyArMjc0NiwxMSBAQCBzdGF0aWMgdm9pZCB0ZWdyYV9zb3JfZHBf ZW5hYmxlKHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlcikKIAltb2RlID0gJmVuY29kZXItPmNy dGMtPnN0YXRlLT5hZGp1c3RlZF9tb2RlOwogCWluZm8gPSAmb3V0cHV0LT5jb25uZWN0b3IuZGlz cGxheV9pbmZvOwogCi0JcG1fcnVudGltZV9nZXRfc3luYyhzb3ItPmRldik7CisJZXJyID0gaG9z dDF4X2NsaWVudF9yZXN1bWUoJnNvci0+Y2xpZW50KTsKKwlpZiAoZXJyIDwgMCkgeworCQlkZXZf ZXJyKHNvci0+ZGV2LCAiZmFpbGVkIHRvIHJlc3VtZTogJWRcbiIsIGVycik7CisJCXJldHVybjsK Kwl9CiAKIAkvKiBzd2l0Y2ggdG8gc2FmZSBwYXJlbnQgY2xvY2sgKi8KIAllcnIgPSB0ZWdyYV9z b3Jfc2V0X3BhcmVudF9jbG9jayhzb3IsIHNvci0+Y2xrX3NhZmUpOwpAQCAtMzE4OSw5ICszMTk3 LDgwIEBAIHN0YXRpYyBpbnQgdGVncmFfc29yX2V4aXQoc3RydWN0IGhvc3QxeF9jbGllbnQgKmNs aWVudCkKIAlyZXR1cm4gMDsKIH0KIAorc3RhdGljIGludCB0ZWdyYV9zb3JfcnVudGltZV9zdXNw ZW5kKHN0cnVjdCBob3N0MXhfY2xpZW50ICpjbGllbnQpCit7CisJc3RydWN0IHRlZ3JhX3NvciAq c29yID0gaG9zdDF4X2NsaWVudF90b19zb3IoY2xpZW50KTsKKwlzdHJ1Y3QgZGV2aWNlICpkZXYg PSBjbGllbnQtPmRldjsKKwlpbnQgZXJyOworCisJaWYgKHNvci0+cnN0KSB7CisJCWVyciA9IHJl c2V0X2NvbnRyb2xfYXNzZXJ0KHNvci0+cnN0KTsKKwkJaWYgKGVyciA8IDApIHsKKwkJCWRldl9l cnIoZGV2LCAiZmFpbGVkIHRvIGFzc2VydCByZXNldDogJWRcbiIsIGVycik7CisJCQlyZXR1cm4g ZXJyOworCQl9CisKKwkJcmVzZXRfY29udHJvbF9yZWxlYXNlKHNvci0+cnN0KTsKKwl9CisKKwl1 c2xlZXBfcmFuZ2UoMTAwMCwgMjAwMCk7CisKKwljbGtfZGlzYWJsZV91bnByZXBhcmUoc29yLT5j bGspOworCXBtX3J1bnRpbWVfcHV0X3N5bmMoZGV2KTsKKworCXJldHVybiAwOworfQorCitzdGF0 aWMgaW50IHRlZ3JhX3Nvcl9ydW50aW1lX3Jlc3VtZShzdHJ1Y3QgaG9zdDF4X2NsaWVudCAqY2xp ZW50KQoreworCXN0cnVjdCB0ZWdyYV9zb3IgKnNvciA9IGhvc3QxeF9jbGllbnRfdG9fc29yKGNs aWVudCk7CisJc3RydWN0IGRldmljZSAqZGV2ID0gY2xpZW50LT5kZXY7CisJaW50IGVycjsKKwor CWVyciA9IHBtX3J1bnRpbWVfZ2V0X3N5bmMoZGV2KTsKKwlpZiAoZXJyIDwgMCkgeworCQlkZXZf ZXJyKGRldiwgImZhaWxlZCB0byBnZXQgcnVudGltZSBQTTogJWRcbiIsIGVycik7CisJCXJldHVy biBlcnI7CisJfQorCisJZXJyID0gY2xrX3ByZXBhcmVfZW5hYmxlKHNvci0+Y2xrKTsKKwlpZiAo ZXJyIDwgMCkgeworCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBlbmFibGUgY2xvY2s6ICVkXG4i LCBlcnIpOworCQlnb3RvIHB1dF9ycG07CisJfQorCisJdXNsZWVwX3JhbmdlKDEwMDAsIDIwMDAp OworCisJaWYgKHNvci0+cnN0KSB7CisJCWVyciA9IHJlc2V0X2NvbnRyb2xfYWNxdWlyZShzb3It PnJzdCk7CisJCWlmIChlcnIgPCAwKSB7CisJCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byBhY3F1 aXJlIHJlc2V0OiAlZFxuIiwgZXJyKTsKKwkJCWdvdG8gZGlzYWJsZV9jbGs7CisJCX0KKworCQll cnIgPSByZXNldF9jb250cm9sX2RlYXNzZXJ0KHNvci0+cnN0KTsKKwkJaWYgKGVyciA8IDApIHsK KwkJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGRlYXNzZXJ0IHJlc2V0OiAlZFxuIiwgZXJyKTsK KwkJCWdvdG8gcmVsZWFzZV9yZXNldDsKKwkJfQorCX0KKworCXJldHVybiAwOworCityZWxlYXNl X3Jlc2V0OgorCXJlc2V0X2NvbnRyb2xfcmVsZWFzZShzb3ItPnJzdCk7CitkaXNhYmxlX2NsazoK KwljbGtfZGlzYWJsZV91bnByZXBhcmUoc29yLT5jbGspOworcHV0X3JwbToKKwlwbV9ydW50aW1l X3B1dF9zeW5jKGRldik7CisJcmV0dXJuIGVycjsKK30KKwogc3RhdGljIGNvbnN0IHN0cnVjdCBo b3N0MXhfY2xpZW50X29wcyBzb3JfY2xpZW50X29wcyA9IHsKIAkuaW5pdCA9IHRlZ3JhX3Nvcl9p bml0LAogCS5leGl0ID0gdGVncmFfc29yX2V4aXQsCisJLnN1c3BlbmQgPSB0ZWdyYV9zb3JfcnVu dGltZV9zdXNwZW5kLAorCS5yZXN1bWUgPSB0ZWdyYV9zb3JfcnVudGltZV9yZXN1bWUsCiB9Owog CiBzdGF0aWMgY29uc3QgdTggdGVncmExMjRfc29yX3hiYXJfY2ZnWzVdID0gewpAQCAtMzg0Miwx MCArMzkyMSw5IEBAIHN0YXRpYyBpbnQgdGVncmFfc29yX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9k ZXZpY2UgKnBkZXYpCiAJaWYgKCFzb3ItPmNsa19wYWQpIHsKIAkJY2hhciAqbmFtZTsKIAotCQll cnIgPSBwbV9ydW50aW1lX2dldF9zeW5jKCZwZGV2LT5kZXYpOworCQllcnIgPSBob3N0MXhfY2xp ZW50X3Jlc3VtZSgmc29yLT5jbGllbnQpOwogCQlpZiAoZXJyIDwgMCkgewotCQkJZGV2X2Vycigm cGRldi0+ZGV2LCAiZmFpbGVkIHRvIGdldCBydW50aW1lIFBNOiAlZFxuIiwKLQkJCQllcnIpOwor CQkJZGV2X2Vycihzb3ItPmRldiwgImZhaWxlZCB0byByZXN1bWU6ICVkXG4iLCBlcnIpOwogCQkJ Z290byByZW1vdmU7CiAJCX0KIApAQCAtMzg1Niw3ICszOTM0LDcgQEAgc3RhdGljIGludCB0ZWdy YV9zb3JfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKIAkJfQogCiAJCXNvci0+ Y2xrX3BhZCA9IHRlZ3JhX2Nsa19zb3JfcGFkX3JlZ2lzdGVyKHNvciwgbmFtZSk7Ci0JCXBtX3J1 bnRpbWVfcHV0KCZwZGV2LT5kZXYpOworCQlob3N0MXhfY2xpZW50X3N1c3BlbmQoJnNvci0+Y2xp ZW50KTsKIAl9CiAKIAlpZiAoSVNfRVJSKHNvci0+Y2xrX3BhZCkpIHsKQEAgLTM5MTIsNjEgKzM5 OTAsNiBAQCBzdGF0aWMgaW50IHRlZ3JhX3Nvcl9yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2Rldmlj ZSAqcGRldikKIAlyZXR1cm4gMDsKIH0KIAotc3RhdGljIGludCB0ZWdyYV9zb3JfcnVudGltZV9z dXNwZW5kKHN0cnVjdCBkZXZpY2UgKmRldikKLXsKLQlzdHJ1Y3QgdGVncmFfc29yICpzb3IgPSBk ZXZfZ2V0X2RydmRhdGEoZGV2KTsKLQlpbnQgZXJyOwotCi0JaWYgKHNvci0+cnN0KSB7Ci0JCWVy ciA9IHJlc2V0X2NvbnRyb2xfYXNzZXJ0KHNvci0+cnN0KTsKLQkJaWYgKGVyciA8IDApIHsKLQkJ CWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGFzc2VydCByZXNldDogJWRcbiIsIGVycik7Ci0JCQly ZXR1cm4gZXJyOwotCQl9Ci0KLQkJcmVzZXRfY29udHJvbF9yZWxlYXNlKHNvci0+cnN0KTsKLQl9 Ci0KLQl1c2xlZXBfcmFuZ2UoMTAwMCwgMjAwMCk7Ci0KLQljbGtfZGlzYWJsZV91bnByZXBhcmUo c29yLT5jbGspOwotCi0JcmV0dXJuIDA7Ci19Ci0KLXN0YXRpYyBpbnQgdGVncmFfc29yX3J1bnRp bWVfcmVzdW1lKHN0cnVjdCBkZXZpY2UgKmRldikKLXsKLQlzdHJ1Y3QgdGVncmFfc29yICpzb3Ig PSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKLQlpbnQgZXJyOwotCi0JZXJyID0gY2xrX3ByZXBhcmVf ZW5hYmxlKHNvci0+Y2xrKTsKLQlpZiAoZXJyIDwgMCkgewotCQlkZXZfZXJyKGRldiwgImZhaWxl ZCB0byBlbmFibGUgY2xvY2s6ICVkXG4iLCBlcnIpOwotCQlyZXR1cm4gZXJyOwotCX0KLQotCXVz bGVlcF9yYW5nZSgxMDAwLCAyMDAwKTsKLQotCWlmIChzb3ItPnJzdCkgewotCQllcnIgPSByZXNl dF9jb250cm9sX2FjcXVpcmUoc29yLT5yc3QpOwotCQlpZiAoZXJyIDwgMCkgewotCQkJZGV2X2Vy cihkZXYsICJmYWlsZWQgdG8gYWNxdWlyZSByZXNldDogJWRcbiIsIGVycik7Ci0JCQljbGtfZGlz YWJsZV91bnByZXBhcmUoc29yLT5jbGspOwotCQkJcmV0dXJuIGVycjsKLQkJfQotCi0JCWVyciA9 IHJlc2V0X2NvbnRyb2xfZGVhc3NlcnQoc29yLT5yc3QpOwotCQlpZiAoZXJyIDwgMCkgewotCQkJ ZGV2X2VycihkZXYsICJmYWlsZWQgdG8gZGVhc3NlcnQgcmVzZXQ6ICVkXG4iLCBlcnIpOwotCQkJ cmVzZXRfY29udHJvbF9yZWxlYXNlKHNvci0+cnN0KTsKLQkJCWNsa19kaXNhYmxlX3VucHJlcGFy ZShzb3ItPmNsayk7Ci0JCQlyZXR1cm4gZXJyOwotCQl9Ci0JfQotCi0JcmV0dXJuIDA7Ci19Ci0K IHN0YXRpYyBpbnQgdGVncmFfc29yX3N1c3BlbmQoc3RydWN0IGRldmljZSAqZGV2KQogewogCXN0 cnVjdCB0ZWdyYV9zb3IgKnNvciA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwpAQCAtMzk3NCw4ICsz OTk3LDkgQEAgc3RhdGljIGludCB0ZWdyYV9zb3Jfc3VzcGVuZChzdHJ1Y3QgZGV2aWNlICpkZXYp CiAKIAlpZiAoc29yLT5oZG1pX3N1cHBseSkgewogCQllcnIgPSByZWd1bGF0b3JfZGlzYWJsZShz b3ItPmhkbWlfc3VwcGx5KTsKLQkJaWYgKGVyciA8IDApCisJCWlmIChlcnIgPCAwKSB7CiAJCQly ZXR1cm4gZXJyOworCQl9CiAJfQogCiAJcmV0dXJuIDA7CkBAIC0zOTk2LDggKzQwMjAsNiBAQCBz dGF0aWMgaW50IHRlZ3JhX3Nvcl9yZXN1bWUoc3RydWN0IGRldmljZSAqZGV2KQogfQogCiBzdGF0 aWMgY29uc3Qgc3RydWN0IGRldl9wbV9vcHMgdGVncmFfc29yX3BtX29wcyA9IHsKLQlTRVRfUlVO VElNRV9QTV9PUFModGVncmFfc29yX3J1bnRpbWVfc3VzcGVuZCwgdGVncmFfc29yX3J1bnRpbWVf cmVzdW1lLAotCQkJICAgTlVMTCkKIAlTRVRfU1lTVEVNX1NMRUVQX1BNX09QUyh0ZWdyYV9zb3Jf c3VzcGVuZCwgdGVncmFfc29yX3Jlc3VtZSkKIH07CiAKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1 L2RybS90ZWdyYS92aWMuYyBiL2RyaXZlcnMvZ3B1L2RybS90ZWdyYS92aWMuYwppbmRleCBhZGU1 NmI4NjBjZjkuLjY3ODk2MWFkYTE3ZiAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL3RlZ3Jh L3ZpYy5jCisrKyBiL2RyaXZlcnMvZ3B1L2RybS90ZWdyYS92aWMuYwpAQCAtNTIsNDggKzUyLDYg QEAgc3RhdGljIHZvaWQgdmljX3dyaXRlbChzdHJ1Y3QgdmljICp2aWMsIHUzMiB2YWx1ZSwgdW5z aWduZWQgaW50IG9mZnNldCkKIAl3cml0ZWwodmFsdWUsIHZpYy0+cmVncyArIG9mZnNldCk7CiB9 CiAKLXN0YXRpYyBpbnQgdmljX3J1bnRpbWVfcmVzdW1lKHN0cnVjdCBkZXZpY2UgKmRldikKLXsK LQlzdHJ1Y3QgdmljICp2aWMgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKLQlpbnQgZXJyOwotCi0J ZXJyID0gY2xrX3ByZXBhcmVfZW5hYmxlKHZpYy0+Y2xrKTsKLQlpZiAoZXJyIDwgMCkKLQkJcmV0 dXJuIGVycjsKLQotCXVzbGVlcF9yYW5nZSgxMCwgMjApOwotCi0JZXJyID0gcmVzZXRfY29udHJv bF9kZWFzc2VydCh2aWMtPnJzdCk7Ci0JaWYgKGVyciA8IDApCi0JCWdvdG8gZGlzYWJsZTsKLQot CXVzbGVlcF9yYW5nZSgxMCwgMjApOwotCi0JcmV0dXJuIDA7Ci0KLWRpc2FibGU6Ci0JY2xrX2Rp c2FibGVfdW5wcmVwYXJlKHZpYy0+Y2xrKTsKLQlyZXR1cm4gZXJyOwotfQotCi1zdGF0aWMgaW50 IHZpY19ydW50aW1lX3N1c3BlbmQoc3RydWN0IGRldmljZSAqZGV2KQotewotCXN0cnVjdCB2aWMg KnZpYyA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwotCWludCBlcnI7Ci0KLQllcnIgPSByZXNldF9j b250cm9sX2Fzc2VydCh2aWMtPnJzdCk7Ci0JaWYgKGVyciA8IDApCi0JCXJldHVybiBlcnI7Ci0K LQl1c2xlZXBfcmFuZ2UoMjAwMCwgNDAwMCk7Ci0KLQljbGtfZGlzYWJsZV91bnByZXBhcmUodmlj LT5jbGspOwotCi0JdmljLT5ib290ZWQgPSBmYWxzZTsKLQotCXJldHVybiAwOwotfQotCiBzdGF0 aWMgaW50IHZpY19ib290KHN0cnVjdCB2aWMgKnZpYykKIHsKICNpZmRlZiBDT05GSUdfSU9NTVVf QVBJCkBAIC0yNDAsOSArMTk4LDYyIEBAIHN0YXRpYyBpbnQgdmljX2V4aXQoc3RydWN0IGhvc3Qx eF9jbGllbnQgKmNsaWVudCkKIAlyZXR1cm4gMDsKIH0KIAorc3RhdGljIGludCB2aWNfcnVudGlt ZV9zdXNwZW5kKHN0cnVjdCBob3N0MXhfY2xpZW50ICpjbGllbnQpCit7CisJc3RydWN0IHRlZ3Jh X2RybV9jbGllbnQgKmRybSA9IGhvc3QxeF90b19kcm1fY2xpZW50KGNsaWVudCk7CisJc3RydWN0 IHZpYyAqdmljID0gdG9fdmljKGRybSk7CisJaW50IGVycjsKKworCWVyciA9IHJlc2V0X2NvbnRy b2xfYXNzZXJ0KHZpYy0+cnN0KTsKKwlpZiAoZXJyIDwgMCkKKwkJcmV0dXJuIGVycjsKKworCXVz bGVlcF9yYW5nZSgyMDAwLCA0MDAwKTsKKworCWNsa19kaXNhYmxlX3VucHJlcGFyZSh2aWMtPmNs ayk7CisJcG1fcnVudGltZV9wdXRfc3luYyh2aWMtPmRldik7CisKKwl2aWMtPmJvb3RlZCA9IGZh bHNlOworCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgdmljX3J1bnRpbWVfcmVzdW1lKHN0 cnVjdCBob3N0MXhfY2xpZW50ICpjbGllbnQpCit7CisJc3RydWN0IHRlZ3JhX2RybV9jbGllbnQg KmRybSA9IGhvc3QxeF90b19kcm1fY2xpZW50KGNsaWVudCk7CisJc3RydWN0IHZpYyAqdmljID0g dG9fdmljKGRybSk7CisJaW50IGVycjsKKworCWVyciA9IHBtX3J1bnRpbWVfZ2V0X3N5bmModmlj LT5kZXYpOworCWlmIChlcnIgPCAwKQorCQlyZXR1cm4gZXJyOworCisJZXJyID0gY2xrX3ByZXBh cmVfZW5hYmxlKHZpYy0+Y2xrKTsKKwlpZiAoZXJyIDwgMCkKKwkJZ290byBwdXRfcnBtOworCisJ dXNsZWVwX3JhbmdlKDEwLCAyMCk7CisKKwllcnIgPSByZXNldF9jb250cm9sX2RlYXNzZXJ0KHZp Yy0+cnN0KTsKKwlpZiAoZXJyIDwgMCkKKwkJZ290byBkaXNhYmxlOworCisJdXNsZWVwX3Jhbmdl KDEwLCAyMCk7CisKKwlyZXR1cm4gMDsKKworcHV0X3JwbToKKwlwbV9ydW50aW1lX3B1dF9zeW5j KHZpYy0+ZGV2KTsKK2Rpc2FibGU6CisJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKHZpYy0+Y2xrKTsK KwlyZXR1cm4gZXJyOworfQorCiBzdGF0aWMgY29uc3Qgc3RydWN0IGhvc3QxeF9jbGllbnRfb3Bz IHZpY19jbGllbnRfb3BzID0gewogCS5pbml0ID0gdmljX2luaXQsCiAJLmV4aXQgPSB2aWNfZXhp dCwKKwkuc3VzcGVuZCA9IHZpY19ydW50aW1lX3N1c3BlbmQsCisJLnJlc3VtZSA9IHZpY19ydW50 aW1lX3Jlc3VtZSwKIH07CiAKIHN0YXRpYyBpbnQgdmljX2xvYWRfZmlybXdhcmUoc3RydWN0IHZp YyAqdmljKQpAQCAtMzE0LDM4ICszMjUsMzcgQEAgc3RhdGljIGludCB2aWNfb3Blbl9jaGFubmVs KHN0cnVjdCB0ZWdyYV9kcm1fY2xpZW50ICpjbGllbnQsCiAJc3RydWN0IHZpYyAqdmljID0gdG9f dmljKGNsaWVudCk7CiAJaW50IGVycjsKIAotCWVyciA9IHBtX3J1bnRpbWVfZ2V0X3N5bmModmlj LT5kZXYpOworCWVyciA9IGhvc3QxeF9jbGllbnRfcmVzdW1lKCZjbGllbnQtPmJhc2UpOwogCWlm IChlcnIgPCAwKQogCQlyZXR1cm4gZXJyOwogCiAJZXJyID0gdmljX2xvYWRfZmlybXdhcmUodmlj KTsKIAlpZiAoZXJyIDwgMCkKLQkJZ290byBycG1fcHV0OworCQlnb3RvIHN1c3BlbmQ7CiAKIAll cnIgPSB2aWNfYm9vdCh2aWMpOwogCWlmIChlcnIgPCAwKQotCQlnb3RvIHJwbV9wdXQ7CisJCWdv dG8gc3VzcGVuZDsKIAogCWNvbnRleHQtPmNoYW5uZWwgPSBob3N0MXhfY2hhbm5lbF9nZXQodmlj LT5jaGFubmVsKTsKIAlpZiAoIWNvbnRleHQtPmNoYW5uZWwpIHsKIAkJZXJyID0gLUVOT01FTTsK LQkJZ290byBycG1fcHV0OworCQlnb3RvIHN1c3BlbmQ7CiAJfQogCiAJcmV0dXJuIDA7CiAKLXJw bV9wdXQ6Ci0JcG1fcnVudGltZV9wdXQodmljLT5kZXYpOworc3VzcGVuZDoKKwlob3N0MXhfY2xp ZW50X3N1c3BlbmQoJmNsaWVudC0+YmFzZSk7CiAJcmV0dXJuIGVycjsKIH0KIAogc3RhdGljIHZv aWQgdmljX2Nsb3NlX2NoYW5uZWwoc3RydWN0IHRlZ3JhX2RybV9jb250ZXh0ICpjb250ZXh0KQog ewotCXN0cnVjdCB2aWMgKnZpYyA9IHRvX3ZpYyhjb250ZXh0LT5jbGllbnQpOworCXN0cnVjdCBo b3N0MXhfY2xpZW50ICpjbGllbnQgPSAmY29udGV4dC0+Y2xpZW50LT5iYXNlOwogCiAJaG9zdDF4 X2NoYW5uZWxfcHV0KGNvbnRleHQtPmNoYW5uZWwpOwotCi0JcG1fcnVudGltZV9wdXQodmljLT5k ZXYpOworCWhvc3QxeF9jbGllbnRfc3VzcGVuZChjbGllbnQpOwogfQogCiBzdGF0aWMgY29uc3Qg c3RydWN0IHRlZ3JhX2RybV9jbGllbnRfb3BzIHZpY19vcHMgPSB7CkBAIC00NzIsMTYgKzQ4Miw5 IEBAIHN0YXRpYyBpbnQgdmljX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCiAJ fQogCiAJcG1fcnVudGltZV9lbmFibGUoJnBkZXYtPmRldik7Ci0JaWYgKCFwbV9ydW50aW1lX2Vu YWJsZWQoJnBkZXYtPmRldikpIHsKLQkJZXJyID0gdmljX3J1bnRpbWVfcmVzdW1lKCZwZGV2LT5k ZXYpOwotCQlpZiAoZXJyIDwgMCkKLQkJCWdvdG8gdW5yZWdpc3Rlcl9jbGllbnQ7Ci0JfQogCiAJ cmV0dXJuIDA7CiAKLXVucmVnaXN0ZXJfY2xpZW50OgotCWhvc3QxeF9jbGllbnRfdW5yZWdpc3Rl cigmdmljLT5jbGllbnQuYmFzZSk7CiBleGl0X2ZhbGNvbjoKIAlmYWxjb25fZXhpdCgmdmljLT5m YWxjb24pOwogCkBAIC00OTMsNiArNDk2LDggQEAgc3RhdGljIGludCB2aWNfcmVtb3ZlKHN0cnVj dCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCiAJc3RydWN0IHZpYyAqdmljID0gcGxhdGZvcm1fZ2V0 X2RydmRhdGEocGRldik7CiAJaW50IGVycjsKIAorCXBtX3J1bnRpbWVfZGlzYWJsZSgmcGRldi0+ ZGV2KTsKKwogCWVyciA9IGhvc3QxeF9jbGllbnRfdW5yZWdpc3RlcigmdmljLT5jbGllbnQuYmFz ZSk7CiAJaWYgKGVyciA8IDApIHsKIAkJZGV2X2VycigmcGRldi0+ZGV2LCAiZmFpbGVkIHRvIHVu cmVnaXN0ZXIgaG9zdDF4IGNsaWVudDogJWRcbiIsCkBAIC01MDAsMjUgKzUwNSwxNSBAQCBzdGF0 aWMgaW50IHZpY19yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKIAkJcmV0dXJu IGVycjsKIAl9CiAKLQlpZiAocG1fcnVudGltZV9lbmFibGVkKCZwZGV2LT5kZXYpKQotCQlwbV9y dW50aW1lX2Rpc2FibGUoJnBkZXYtPmRldik7Ci0JZWxzZQotCQl2aWNfcnVudGltZV9zdXNwZW5k KCZwZGV2LT5kZXYpOwotCiAJZmFsY29uX2V4aXQoJnZpYy0+ZmFsY29uKTsKIAogCXJldHVybiAw OwogfQogCi1zdGF0aWMgY29uc3Qgc3RydWN0IGRldl9wbV9vcHMgdmljX3BtX29wcyA9IHsKLQlT RVRfUlVOVElNRV9QTV9PUFModmljX3J1bnRpbWVfc3VzcGVuZCwgdmljX3J1bnRpbWVfcmVzdW1l LCBOVUxMKQotfTsKLQogc3RydWN0IHBsYXRmb3JtX2RyaXZlciB0ZWdyYV92aWNfZHJpdmVyID0g ewogCS5kcml2ZXIgPSB7CiAJCS5uYW1lID0gInRlZ3JhLXZpYyIsCiAJCS5vZl9tYXRjaF90YWJs ZSA9IHRlZ3JhX3ZpY19vZl9tYXRjaCwKLQkJLnBtID0gJnZpY19wbV9vcHMKIAl9LAogCS5wcm9i ZSA9IHZpY19wcm9iZSwKIAkucmVtb3ZlID0gdmljX3JlbW92ZSwKZGlmZiAtLWdpdCBhL2RyaXZl cnMvZ3B1L2hvc3QxeC9idXMuYyBiL2RyaXZlcnMvZ3B1L2hvc3QxeC9idXMuYwppbmRleCA1MGQ1 MDAzNDVkMDQuLjZhOTk1ZGI1MWQ2ZCAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvaG9zdDF4L2J1 cy5jCisrKyBiL2RyaXZlcnMvZ3B1L2hvc3QxeC9idXMuYwpAQCAtNzEwLDYgKzcxMCwxMCBAQCBp bnQgaG9zdDF4X2NsaWVudF9yZWdpc3RlcihzdHJ1Y3QgaG9zdDF4X2NsaWVudCAqY2xpZW50KQog CXN0cnVjdCBob3N0MXggKmhvc3QxeDsKIAlpbnQgZXJyOwogCisJSU5JVF9MSVNUX0hFQUQoJmNs aWVudC0+bGlzdCk7CisJbXV0ZXhfaW5pdCgmY2xpZW50LT5sb2NrKTsKKwljbGllbnQtPnVzZWNv dW50ID0gMDsKKwogCW11dGV4X2xvY2soJmRldmljZXNfbG9jayk7CiAKIAlsaXN0X2Zvcl9lYWNo X2VudHJ5KGhvc3QxeCwgJmRldmljZXMsIGxpc3QpIHsKQEAgLTc2OCwzICs3NzIsNzQgQEAgaW50 IGhvc3QxeF9jbGllbnRfdW5yZWdpc3RlcihzdHJ1Y3QgaG9zdDF4X2NsaWVudCAqY2xpZW50KQog CXJldHVybiAwOwogfQogRVhQT1JUX1NZTUJPTChob3N0MXhfY2xpZW50X3VucmVnaXN0ZXIpOwor CitpbnQgaG9zdDF4X2NsaWVudF9zdXNwZW5kKHN0cnVjdCBob3N0MXhfY2xpZW50ICpjbGllbnQp Cit7CisJaW50IGVyciA9IDA7CisKKwltdXRleF9sb2NrKCZjbGllbnQtPmxvY2spOworCisJaWYg KGNsaWVudC0+dXNlY291bnQgPT0gMSkgeworCQlpZiAoY2xpZW50LT5vcHMgJiYgY2xpZW50LT5v cHMtPnN1c3BlbmQpIHsKKwkJCWVyciA9IGNsaWVudC0+b3BzLT5zdXNwZW5kKGNsaWVudCk7CisJ CQlpZiAoZXJyIDwgMCkKKwkJCQlnb3RvIHVubG9jazsKKwkJfQorCX0KKworCWNsaWVudC0+dXNl Y291bnQtLTsKKwlkZXZfZGJnKGNsaWVudC0+ZGV2LCAidXNlIGNvdW50OiAldVxuIiwgY2xpZW50 LT51c2Vjb3VudCk7CisKKwlpZiAoY2xpZW50LT5wYXJlbnQpIHsKKwkJZXJyID0gaG9zdDF4X2Ns aWVudF9zdXNwZW5kKGNsaWVudC0+cGFyZW50KTsKKwkJaWYgKGVyciA8IDApCisJCQlnb3RvIHJl c3VtZTsKKwl9CisKKwlnb3RvIHVubG9jazsKKworcmVzdW1lOgorCWlmIChjbGllbnQtPnVzZWNv dW50ID09IDApCisJCWlmIChjbGllbnQtPm9wcyAmJiBjbGllbnQtPm9wcy0+cmVzdW1lKQorCQkJ Y2xpZW50LT5vcHMtPnJlc3VtZShjbGllbnQpOworCisJY2xpZW50LT51c2Vjb3VudCsrOwordW5s b2NrOgorCW11dGV4X3VubG9jaygmY2xpZW50LT5sb2NrKTsKKwlyZXR1cm4gZXJyOworfQorRVhQ T1JUX1NZTUJPTChob3N0MXhfY2xpZW50X3N1c3BlbmQpOworCitpbnQgaG9zdDF4X2NsaWVudF9y ZXN1bWUoc3RydWN0IGhvc3QxeF9jbGllbnQgKmNsaWVudCkKK3sKKwlpbnQgZXJyID0gMDsKKwor CW11dGV4X2xvY2soJmNsaWVudC0+bG9jayk7CisKKwlpZiAoY2xpZW50LT5wYXJlbnQpIHsKKwkJ ZXJyID0gaG9zdDF4X2NsaWVudF9yZXN1bWUoY2xpZW50LT5wYXJlbnQpOworCQlpZiAoZXJyIDwg MCkKKwkJCWdvdG8gdW5sb2NrOworCX0KKworCWlmIChjbGllbnQtPnVzZWNvdW50ID09IDApIHsK KwkJaWYgKGNsaWVudC0+b3BzICYmIGNsaWVudC0+b3BzLT5yZXN1bWUpIHsKKwkJCWVyciA9IGNs aWVudC0+b3BzLT5yZXN1bWUoY2xpZW50KTsKKwkJCWlmIChlcnIgPCAwKQorCQkJCWdvdG8gc3Vz cGVuZDsKKwkJfQorCX0KKworCWNsaWVudC0+dXNlY291bnQrKzsKKwlkZXZfZGJnKGNsaWVudC0+ ZGV2LCAidXNlIGNvdW50OiAldVxuIiwgY2xpZW50LT51c2Vjb3VudCk7CisKKwlnb3RvIHVubG9j azsKKworc3VzcGVuZDoKKwlpZiAoY2xpZW50LT5wYXJlbnQpCisJCWhvc3QxeF9jbGllbnRfc3Vz cGVuZChjbGllbnQtPnBhcmVudCk7Cit1bmxvY2s6CisJbXV0ZXhfdW5sb2NrKCZjbGllbnQtPmxv Y2spOworCXJldHVybiBlcnI7Cit9CitFWFBPUlRfU1lNQk9MKGhvc3QxeF9jbGllbnRfcmVzdW1l KTsKZGlmZiAtLWdpdCBhL2luY2x1ZGUvbGludXgvaG9zdDF4LmggYi9pbmNsdWRlL2xpbnV4L2hv c3QxeC5oCmluZGV4IDQ3MGExOTNhOWZlZC4uMDI1NGViY2RjMGE3IDEwMDY0NAotLS0gYS9pbmNs dWRlL2xpbnV4L2hvc3QxeC5oCisrKyBiL2luY2x1ZGUvbGludXgvaG9zdDF4LmgKQEAgLTI0LDEw ICsyNCwxNCBAQCBzdHJ1Y3QgaW9tbXVfZ3JvdXA7CiAgKiBzdHJ1Y3QgaG9zdDF4X2NsaWVudF9v cHMgLSBob3N0MXggY2xpZW50IG9wZXJhdGlvbnMKICAqIEBpbml0OiBob3N0MXggY2xpZW50IGlu aXRpYWxpemF0aW9uIGNvZGUKICAqIEBleGl0OiBob3N0MXggY2xpZW50IHRlYXIgZG93biBjb2Rl CisgKiBAc3VzcGVuZDogaG9zdDF4IGNsaWVudCBzdXNwZW5kIGNvZGUKKyAqIEByZXN1bWU6IGhv c3QxeCBjbGllbnQgcmVzdW1lIGNvZGUKICAqLwogc3RydWN0IGhvc3QxeF9jbGllbnRfb3BzIHsK IAlpbnQgKCppbml0KShzdHJ1Y3QgaG9zdDF4X2NsaWVudCAqY2xpZW50KTsKIAlpbnQgKCpleGl0 KShzdHJ1Y3QgaG9zdDF4X2NsaWVudCAqY2xpZW50KTsKKwlpbnQgKCpzdXNwZW5kKShzdHJ1Y3Qg aG9zdDF4X2NsaWVudCAqY2xpZW50KTsKKwlpbnQgKCpyZXN1bWUpKHN0cnVjdCBob3N0MXhfY2xp ZW50ICpjbGllbnQpOwogfTsKIAogLyoqCkBAIC01NSw2ICs1OSwxMCBAQCBzdHJ1Y3QgaG9zdDF4 X2NsaWVudCB7CiAKIAlzdHJ1Y3QgaG9zdDF4X3N5bmNwdCAqKnN5bmNwdHM7CiAJdW5zaWduZWQg aW50IG51bV9zeW5jcHRzOworCisJc3RydWN0IGhvc3QxeF9jbGllbnQgKnBhcmVudDsKKwl1bnNp Z25lZCBpbnQgdXNlY291bnQ7CisJc3RydWN0IG11dGV4IGxvY2s7CiB9OwogCiAvKgpAQCAtMzA5 LDYgKzMxNyw5IEBAIGludCBob3N0MXhfZGV2aWNlX2V4aXQoc3RydWN0IGhvc3QxeF9kZXZpY2Ug KmRldmljZSk7CiBpbnQgaG9zdDF4X2NsaWVudF9yZWdpc3RlcihzdHJ1Y3QgaG9zdDF4X2NsaWVu dCAqY2xpZW50KTsKIGludCBob3N0MXhfY2xpZW50X3VucmVnaXN0ZXIoc3RydWN0IGhvc3QxeF9j bGllbnQgKmNsaWVudCk7CiAKK2ludCBob3N0MXhfY2xpZW50X3N1c3BlbmQoc3RydWN0IGhvc3Qx eF9jbGllbnQgKmNsaWVudCk7CitpbnQgaG9zdDF4X2NsaWVudF9yZXN1bWUoc3RydWN0IGhvc3Qx eF9jbGllbnQgKmNsaWVudCk7CisKIHN0cnVjdCB0ZWdyYV9taXBpX2RldmljZTsKIAogc3RydWN0 IHRlZ3JhX21pcGlfZGV2aWNlICp0ZWdyYV9taXBpX3JlcXVlc3Qoc3RydWN0IGRldmljZSAqZGV2 aWNlKTsKLS0gCjIuMjMuMAoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX18KZHJpLWRldmVsIG1haWxpbmcgbGlzdApkcmktZGV2ZWxAbGlzdHMuZnJlZWRlc2t0 b3Aub3JnCmh0dHBzOi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vZHJp LWRldmVs 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=-9.6 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6D5E8C432C0 for ; Tue, 3 Dec 2019 16:27:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 21C21206E4 for ; Tue, 3 Dec 2019 16:27:45 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="LzKt/BxI" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726319AbfLCQ1o (ORCPT ); Tue, 3 Dec 2019 11:27:44 -0500 Received: from mail-wm1-f66.google.com ([209.85.128.66]:39363 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725848AbfLCQ1o (ORCPT ); Tue, 3 Dec 2019 11:27:44 -0500 Received: by mail-wm1-f66.google.com with SMTP id s14so4201018wmh.4; Tue, 03 Dec 2019 08:27:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=MWXyc3cbmLp6XuhOiEfC1K5ggWUQ9Ztw5IFqki2F44M=; b=LzKt/BxIzAZWxhh71XUpaS7nxSiiEWZThlBlIBCnU5q1Z6GDGXz20eVCWwM3mH/ATb vXIc0DBb/sDBCsvZfKJOqiID8PM7unJFv4UlZXT6pr0dbXxIjT1WqTCKNP4vJykN3f5t MRx7q2uFI63+vhdF5NN6Hxhd9BDiMeZi3bw1bmU7wI3s0vhLATeVqAg2Tw5HlDTBW3Ol JD3wHShuTJKQLqcSD1A9+iix2OuUfU9MsfaTA3bR45xlQ0nJ+QNEQFzlysRUGAAytBy6 8Hs6GLJWuwaSoTF5QlRIOX/Hs6ogwI0RfwvP1NOCAIMxB9mxQOVpt0+yvT4ZCa2MHUDk w3DQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=MWXyc3cbmLp6XuhOiEfC1K5ggWUQ9Ztw5IFqki2F44M=; b=pTDbYZj1o5Q65/LWbMQYlY4bG1CCm5qzfEaVAiDWEVqNw4ufLXxUNFGzDsswaJB+Ju RsB5GsqyZUhSMVJYjZzh0HXuhTvAtf3+GVFdgjtUwxXDeNJBRWgJwkM/r8yvzki0agCC 1tkGs7UDCswFRjmKBGkkj1suUYRuczrJjwieFq7dixltNWgLN1AxiWIZDg7RYtykvdq/ Dbj6VpDwnRt5a2eVhEvSuEbxcR3yfx/2+1OSQEqqNg5E7VwUthvHLc4qZrtjGH0/obBU 8vzuqRo1F0x9WTPNqYNNs1b77zFwIti4Sdbbn0/jrW6hiFgvN+yqUmLBBx/okDaH5hfu Gq4g== X-Gm-Message-State: APjAAAVsX+uPrwCvVp074vvTk6PB6xTG/pfDDlwtCQWBhsPmhdp7KnjO lFZBf8sdopzQzH13E3D1wkd46po2NDg= X-Google-Smtp-Source: APXvYqwginI3Kug+SHYDe4cNioC/iMH34IxdChvFJlHBbUDSsw7mYCx7aVOqIMgSBPxFO3Fqm4eRFw== X-Received: by 2002:a7b:cd8b:: with SMTP id y11mr28308618wmj.95.1575390458096; Tue, 03 Dec 2019 08:27:38 -0800 (PST) Received: from localhost (pD9E518ED.dip0.t-ipconnect.de. [217.229.24.237]) by smtp.gmail.com with ESMTPSA id c9sm3342550wmb.42.2019.12.03.08.27.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Dec 2019 08:27:37 -0800 (PST) From: Thierry Reding To: Thierry Reding Cc: Daniel Vetter , "Rafael J. Wysocki" , dri-devel@lists.freedesktop.org, linux-pm@vger.kernel.org, linux-tegra@vger.kernel.org Subject: [PATCH 2/2] drm/tegra: Do not implement runtime PM Date: Tue, 3 Dec 2019 17:27:33 +0100 Message-Id: <20191203162733.1436800-2-thierry.reding@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191203162733.1436800-1-thierry.reding@gmail.com> References: <20191203162733.1436800-1-thierry.reding@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org 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); -- 2.23.0