From mboxrd@z Thu Jan 1 00:00:00 1970 From: Fabrizio Castro Subject: [RFC] drm/bridge/sii902x: Fix EDID readback Date: Wed, 31 Oct 2018 12:57:46 +0000 Message-ID: <1540990667-14109-1-git-send-email-fabrizio.castro@bp.renesas.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Archit Taneja , Andrzej Hajda , David Airlie , Peter Rosin , Wolfram Sang Cc: Fabrizio Castro , Chris Paterson , Geert Uytterhoeven , Boris Brezillon , dri-devel@lists.freedesktop.org, Biju Das , linux-renesas-soc@vger.kernel.org, Simon Horman , Laurent Pinchart , linux-i2c@vger.kernel.org List-Id: linux-i2c@vger.kernel.org V2hpbGUgYWRkaW5nIFNpSTkwMjJBIHN1cHBvcnQgdG8gdGhlIGl3ZzIzcyBib2FyZCBpdCBjYW1l IHVwCnRoYXQgd2hlbiB0aGUgSERNSSB0cmFuc21pdHRlciBpcyBpbiBwYXNzIHRocm91Z2ggbW9k ZSB0aGUKZGV2aWNlIGlzIG5vdCBjb21wbGlhbnQgd2l0aCB0aGUgSTJDIHNwZWNpZmljYXRpb24g YW55bW9yZSwKYXMgaXQgcmVxdWlyZXMgYSBmYXIgYmlnZ2VyIHRidWYgZHVlIHRvIGEgZGVsYXkg dGhlIEhETUkKdHJhbnNtaXR0ZXIgaXMgYWRkaW5nIHdoZW4gcmVsYXlpbmcgdGhlIFNUT1AgY29u ZGl0aW9uIG9uIHRoZQptb25pdG9yIGkyYyBzaWRlIG9mIHRoaW5ncy4gV2hlbiBub3QgcHJvdmlk aW5nIGFuIGFwcHJvcHJpYXRlCmRlbGF5IGFmdGVyIHRoZSBTVE9QIGNvbmRpdGlvbiB0aGUgaTJj IGJ1cyB3b3VsZCBnZXQgc3R1Y2suCkFsc28sIGFueSBvdGhlciB0cmFmZmljIG9uIHRoZSBidXMg d2hpbGUgdGFsa2luZyB0byB0aGUgbW9uaXRvcgptYXkgY2F1c2UgdGhlIHRyYW5zYWN0aW9uIHRv IGZhaWwgb3IgZXZlbiBjYXVzZSBpc3N1ZXMgd2l0aCB0aGUKaTJjIGJ1cyBhcyB3ZWxsLgpJMmMt Z2F0ZXMgc2VlbWVkIHRvIHJlYWNoIGNvbnNlbnQgYXMgYSBwb3NzaWJsZSB3YXkgdG8gYWRkcmVz cwp0aGVzZSBpc3N1ZXMsIGFuZCBhcyBzdWNoIHRoaXMgcGF0Y2ggaXMgaW1wbGVtZW50aW5nIGEg c29sdXRpb24KYmFzZWQgb24gdGhhdC4gU2luY2Ugb3RoZXJzIGFyZSBjbGVhcmx5IHJlbHlpbmcg b24gdGhlIGN1cnJlbnQKaW1wbGVtZW50YXRpb24gb2YgdGhlIGRyaXZlciwgdGhpcyBwYXRjaCB3 b24ndCByZXF1aXJlIGFueSBEVApjaGFuZ2VzLgpTaW5jZSB3ZSBkb24ndCB3YW50IGFueSBpbnRl cmZlcmVuY2UgZHVyaW5nIHRoZSBEREMgQnVzClJlcXVlc3QvR3JhbnQgcHJvY2VkdXJlIGFuZCB3 aGlsZSB0YWxraW5nIHRvIHRoZSBtb25pdG9yLCB3ZSBoYXZlCnRvIHVzZSB0aGUgYWRhcHRlciBs b2NraW5nIHByaW1pdGl2ZXMgcmF0aGVyIHRoYW4gdGhlIGkyYy1tdXgKbG9ja2luZyBwcmltaXRp dmVzLCBidXQgaW4gb3JkZXIgdG8gYWNoaWV2ZSB0aGF0IEkgaGFkIHRvIGdldApyaWQgb2YgcmVn bWFwLgoKU2lnbmVkLW9mZi1ieTogRmFicml6aW8gQ2FzdHJvIDxmYWJyaXppby5jYXN0cm9AYnAu cmVuZXNhcy5jb20+Ci0tLQpEZWFyIEFsbCwKCnRoaXMgaXMgYSBmb2xsb3cgdXAgdG86Cmh0dHBz Oi8vd3d3Lm1haWwtYXJjaGl2ZS5jb20vbGludXgtcmVuZXNhcy1zb2NAdmdlci5rZXJuZWwub3Jn L21zZzMyMDcyLmh0bWwKCkNvbW1lbnRzIHZlcnkgd2VsY29tZSEKClRoYW5rcywKRmFiCgogZHJp dmVycy9ncHUvZHJtL2JyaWRnZS9zaWk5MDJ4LmMgfCA0MDQgKysrKysrKysrKysrKysrKysrKysr KysrKystLS0tLS0tLS0tLS0tCiAxIGZpbGUgY2hhbmdlZCwgMjc0IGluc2VydGlvbnMoKyksIDEz MCBkZWxldGlvbnMoLSkKCmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vYnJpZGdlL3NpaTkw MnguYyBiL2RyaXZlcnMvZ3B1L2RybS9icmlkZ2Uvc2lpOTAyeC5jCmluZGV4IGU1OWExMzUuLjEz N2EwNWEgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2RybS9icmlkZ2Uvc2lpOTAyeC5jCisrKyBi L2RyaXZlcnMvZ3B1L2RybS9icmlkZ2Uvc2lpOTAyeC5jCkBAIC0yMSw5ICsyMSw5IEBACiAgKi8K IAogI2luY2x1ZGUgPGxpbnV4L2dwaW8vY29uc3VtZXIuaD4KKyNpbmNsdWRlIDxsaW51eC9pMmMt bXV4Lmg+CiAjaW5jbHVkZSA8bGludXgvaTJjLmg+CiAjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+ Ci0jaW5jbHVkZSA8bGludXgvcmVnbWFwLmg+CiAKICNpbmNsdWRlIDxkcm0vZHJtUC5oPgogI2lu Y2x1ZGUgPGRybS9kcm1fYXRvbWljX2hlbHBlci5oPgpAQCAtODIsMTIgKzgyLDEzMCBAQAogCiBz dHJ1Y3Qgc2lpOTAyeCB7CiAJc3RydWN0IGkyY19jbGllbnQgKmkyYzsKLQlzdHJ1Y3QgcmVnbWFw ICpyZWdtYXA7CiAJc3RydWN0IGRybV9icmlkZ2UgYnJpZGdlOwogCXN0cnVjdCBkcm1fY29ubmVj dG9yIGNvbm5lY3RvcjsKIAlzdHJ1Y3QgZ3Bpb19kZXNjICpyZXNldF9ncGlvOworCXN0cnVjdCBp MmNfbXV4X2NvcmUgKmkyY211eDsKIH07CiAKK3N0YXRpYyBpbnQgc2lpOTAyeF90cmFuc2Zlcl9y ZWFkKHN0cnVjdCBpMmNfY2xpZW50ICppMmMsIHU4IHJlZywgdTggKnZhbCwKKwkJCQkgdTE2IGxl biwgYm9vbCBsb2NrZWQpCit7CisJc3RydWN0IGkyY19tc2cgeGZlcltdID0geworCQl7CisJCQku YWRkciA9IGkyYy0+YWRkciwKKwkJCS5mbGFncyA9IDAsCisJCQkubGVuID0gMSwKKwkJCS5idWYg PSAmcmVnLAorCQl9LCB7CisJCQkuYWRkciA9IGkyYy0+YWRkciwKKwkJCS5mbGFncyA9IEkyQ19N X1JELAorCQkJLmxlbiA9IGxlbiwKKwkJCS5idWYgPSB2YWwsCisJCX0KKwl9OworCXVuc2lnbmVk IGNoYXIgeGZlcnMgPSBBUlJBWV9TSVpFKHhmZXIpOworCWludCByZXQsIHJldHJpZXMgPSA1Owor CisJZG8geworCQlpZiAobG9ja2VkKQorCQkJcmV0ID0gaTJjX3RyYW5zZmVyKGkyYy0+YWRhcHRl ciwgeGZlciwgeGZlcnMpOworCQllbHNlCisJCQlyZXQgPSBfX2kyY190cmFuc2ZlcihpMmMtPmFk YXB0ZXIsIHhmZXIsIHhmZXJzKTsKKwkJaWYgKHJldCA8IDApCisJCQlyZXR1cm4gcmV0OworCX0g d2hpbGUgKHJldCAhPSB4ZmVycyAmJiAtLXJldHJpZXMpOworCXJldHVybiByZXQgPT0geGZlcnMg PyAwIDogLTE7Cit9CisKK3N0YXRpYyBpbnQgc2lpOTAyeF9idWxrX3JlYWQoc3RydWN0IGkyY19j bGllbnQgKmkyYywgdTggcmVnLCB1OCAqdmFsLCB1MTYgbGVuKQoreworCXJldHVybiBzaWk5MDJ4 X3RyYW5zZmVyX3JlYWQoaTJjLCByZWcsIHZhbCwgbGVuLCB0cnVlKTsKK30KKworc3RhdGljIGlu dCBfX3NpaTkwMnhfYnVsa19yZWFkKHN0cnVjdCBpMmNfY2xpZW50ICppMmMsIHU4IHJlZywgdTgg KnZhbCwgdTE2IGxlbikKK3sKKwlyZXR1cm4gc2lpOTAyeF90cmFuc2Zlcl9yZWFkKGkyYywgcmVn LCB2YWwsIGxlbiwgZmFsc2UpOworfQorCitzdGF0aWMgaW50IHNpaTkwMnhfcmVhZChzdHJ1Y3Qg aTJjX2NsaWVudCAqaTJjLCB1OCByZWcsIHU4ICp2YWwpCit7CisJcmV0dXJuIHNpaTkwMnhfYnVs a19yZWFkKGkyYywgcmVnLCB2YWwsIDEpOworfQorCitzdGF0aWMgaW50IF9fc2lpOTAyeF9yZWFk KHN0cnVjdCBpMmNfY2xpZW50ICppMmMsIHU4IHJlZywgdTggKnZhbCkKK3sKKwlyZXR1cm4gX19z aWk5MDJ4X2J1bGtfcmVhZChpMmMsIHJlZywgdmFsLCAxKTsKK30KKworc3RhdGljIGludCBzaWk5 MDJ4X3RyYW5zZmVyX3dyaXRlKHN0cnVjdCBpMmNfY2xpZW50ICppMmMsIHU4ICp2YWwsCisJCQkJ IHUxNiBsZW4sIGJvb2wgbG9ja2VkKQoreworCXN0cnVjdCBpMmNfbXNnIHhmZXIgPSB7CisJCS5h ZGRyID0gaTJjLT5hZGRyLAorCQkuZmxhZ3MgPSAwLAorCQkubGVuID0gbGVuLAorCQkuYnVmID0g dmFsLAorCX07CisJaW50IHJldCwgcmV0cmllcyA9IDU7CisKKwlkbyB7CisJCWlmIChsb2NrZWQp CisJCQlyZXQgPSBpMmNfdHJhbnNmZXIoaTJjLT5hZGFwdGVyLCAmeGZlciwgMSk7CisJCWVsc2UK KwkJCXJldCA9IF9faTJjX3RyYW5zZmVyKGkyYy0+YWRhcHRlciwgJnhmZXIsIDEpOworCQlpZiAo cmV0IDwgMCkKKwkJCXJldHVybiByZXQ7CisJfSB3aGlsZSAoIXJldCAmJiAtLXJldHJpZXMpOwor CXJldHVybiAhcmV0ID8gLTEgOiAwOworfQorCitzdGF0aWMgaW50IHNpaTkwMnhfYnVsa193cml0 ZShzdHJ1Y3QgaTJjX2NsaWVudCAqaTJjLCB1OCAqdmFsLCB1MTYgbGVuKQoreworCXJldHVybiBz aWk5MDJ4X3RyYW5zZmVyX3dyaXRlKGkyYywgdmFsLCBsZW4sIHRydWUpOworfQorCitzdGF0aWMg aW50IHNpaTkwMnhfd3JpdGUoc3RydWN0IGkyY19jbGllbnQgKmkyYywgdTggcmVnLCB1OCB2YWwp Cit7CisJdTggZGF0YVsyXSA9IHtyZWcsIHZhbH07CisKKwlyZXR1cm4gc2lpOTAyeF90cmFuc2Zl cl93cml0ZShpMmMsIGRhdGEsIDIsIHRydWUpOworfQorCitzdGF0aWMgaW50IF9fc2lpOTAyeF93 cml0ZShzdHJ1Y3QgaTJjX2NsaWVudCAqaTJjLCB1OCByZWcsIHU4IHZhbCkKK3sKKwl1OCBkYXRh WzJdID0ge3JlZywgdmFsfTsKKworCXJldHVybiBzaWk5MDJ4X3RyYW5zZmVyX3dyaXRlKGkyYywg ZGF0YSwgMiwgZmFsc2UpOworfQorCitzdGF0aWMgaW50IHNpaTkwMnhfdXBkYXRlX2JpdHMoc3Ry dWN0IGkyY19jbGllbnQgKmkyYywgdTggcmVnLCB1OCBtYXNrLCB1OCB2YWwpCit7CisJaW50IHJl dDsKKwl1OCBzdGF0dXM7CisKKwlyZXQgPSBzaWk5MDJ4X3JlYWQoaTJjLCByZWcsICZzdGF0dXMp OworCWlmIChyZXQpCisJCXJldHVybiByZXQ7CisJc3RhdHVzICY9IH5tYXNrOworCXN0YXR1cyB8 PSB2YWwgJiBtYXNrOworCXJldHVybiBzaWk5MDJ4X3dyaXRlKGkyYywgcmVnLCBzdGF0dXMpOwor fQorCitzdGF0aWMgaW50IF9fc2lpOTAyeF91cGRhdGVfYml0cyhzdHJ1Y3QgaTJjX2NsaWVudCAq aTJjLCB1OCByZWcsIHU4IG1hc2ssCisJCQkJIHU4IHZhbCkKK3sKKwlpbnQgcmV0OworCXU4IHN0 YXR1czsKKworCXJldCA9IF9fc2lpOTAyeF9yZWFkKGkyYywgcmVnLCAmc3RhdHVzKTsKKwlpZiAo cmV0KQorCQlyZXR1cm4gcmV0OworCXN0YXR1cyAmPSB+bWFzazsKKwlzdGF0dXMgfD0gdmFsICYg bWFzazsKKwlyZXR1cm4gX19zaWk5MDJ4X3dyaXRlKGkyYywgcmVnLCBzdGF0dXMpOworfQorCiBz dGF0aWMgaW5saW5lIHN0cnVjdCBzaWk5MDJ4ICpicmlkZ2VfdG9fc2lpOTAyeChzdHJ1Y3QgZHJt X2JyaWRnZSAqYnJpZGdlKQogewogCXJldHVybiBjb250YWluZXJfb2YoYnJpZGdlLCBzdHJ1Y3Qg c2lpOTAyeCwgYnJpZGdlKTsKQEAgLTExNSw5ICsyMzMsOSBAQCBzdGF0aWMgZW51bSBkcm1fY29u bmVjdG9yX3N0YXR1cwogc2lpOTAyeF9jb25uZWN0b3JfZGV0ZWN0KHN0cnVjdCBkcm1fY29ubmVj dG9yICpjb25uZWN0b3IsIGJvb2wgZm9yY2UpCiB7CiAJc3RydWN0IHNpaTkwMnggKnNpaTkwMngg PSBjb25uZWN0b3JfdG9fc2lpOTAyeChjb25uZWN0b3IpOwotCXVuc2lnbmVkIGludCBzdGF0dXM7 CisJdTggc3RhdHVzOwogCi0JcmVnbWFwX3JlYWQoc2lpOTAyeC0+cmVnbWFwLCBTSUk5MDJYX0lO VF9TVEFUVVMsICZzdGF0dXMpOworCXNpaTkwMnhfcmVhZChzaWk5MDJ4LT5pMmMsIFNJSTkwMlhf SU5UX1NUQVRVUywgJnN0YXR1cyk7CiAKIAlyZXR1cm4gKHN0YXR1cyAmIFNJSTkwMlhfUExVR0dF RF9TVEFUVVMpID8KIAkgICAgICAgY29ubmVjdG9yX3N0YXR1c19jb25uZWN0ZWQgOiBjb25uZWN0 b3Jfc3RhdHVzX2Rpc2Nvbm5lY3RlZDsKQEAgLTEzNSw0MSArMjUzLDExIEBAIHN0YXRpYyBjb25z dCBzdHJ1Y3QgZHJtX2Nvbm5lY3Rvcl9mdW5jcyBzaWk5MDJ4X2Nvbm5lY3Rvcl9mdW5jcyA9IHsK IHN0YXRpYyBpbnQgc2lpOTAyeF9nZXRfbW9kZXMoc3RydWN0IGRybV9jb25uZWN0b3IgKmNvbm5l Y3RvcikKIHsKIAlzdHJ1Y3Qgc2lpOTAyeCAqc2lpOTAyeCA9IGNvbm5lY3Rvcl90b19zaWk5MDJ4 KGNvbm5lY3Rvcik7Ci0Jc3RydWN0IHJlZ21hcCAqcmVnbWFwID0gc2lpOTAyeC0+cmVnbWFwOwog CXUzMiBidXNfZm9ybWF0ID0gTUVESUFfQlVTX0ZNVF9SR0I4ODhfMVgyNDsKLQlzdHJ1Y3QgZGV2 aWNlICpkZXYgPSAmc2lpOTAyeC0+aTJjLT5kZXY7Ci0JdW5zaWduZWQgbG9uZyB0aW1lb3V0Owot CXVuc2lnbmVkIGludCByZXRyaWVzOwotCXVuc2lnbmVkIGludCBzdGF0dXM7CiAJc3RydWN0IGVk aWQgKmVkaWQ7Ci0JaW50IG51bSA9IDA7Ci0JaW50IHJldDsKLQotCXJldCA9IHJlZ21hcF91cGRh dGVfYml0cyhyZWdtYXAsIFNJSTkwMlhfU1lTX0NUUkxfREFUQSwKLQkJCQkgU0lJOTAyWF9TWVNf Q1RSTF9ERENfQlVTX1JFUSwKLQkJCQkgU0lJOTAyWF9TWVNfQ1RSTF9ERENfQlVTX1JFUSk7Ci0J aWYgKHJldCkKLQkJcmV0dXJuIHJldDsKKwlpbnQgbnVtID0gMCwgcmV0OwogCi0JdGltZW91dCA9 IGppZmZpZXMgKwotCQkgIG1zZWNzX3RvX2ppZmZpZXMoU0lJOTAyWF9JMkNfQlVTX0FDUVVJU0lU SU9OX1RJTUVPVVRfTVMpOwotCWRvIHsKLQkJcmV0ID0gcmVnbWFwX3JlYWQocmVnbWFwLCBTSUk5 MDJYX1NZU19DVFJMX0RBVEEsICZzdGF0dXMpOwotCQlpZiAocmV0KQotCQkJcmV0dXJuIHJldDsK LQl9IHdoaWxlICghKHN0YXR1cyAmIFNJSTkwMlhfU1lTX0NUUkxfRERDX0JVU19HUlREKSAmJgot CQkgdGltZV9iZWZvcmUoamlmZmllcywgdGltZW91dCkpOwotCi0JaWYgKCEoc3RhdHVzICYgU0lJ OTAyWF9TWVNfQ1RSTF9ERENfQlVTX0dSVEQpKSB7Ci0JCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRv IGFjcXVpcmUgdGhlIGkyYyBidXNcbiIpOwotCQlyZXR1cm4gLUVUSU1FRE9VVDsKLQl9Ci0KLQly ZXQgPSByZWdtYXBfd3JpdGUocmVnbWFwLCBTSUk5MDJYX1NZU19DVFJMX0RBVEEsIHN0YXR1cyk7 Ci0JaWYgKHJldCkKLQkJcmV0dXJuIHJldDsKLQotCWVkaWQgPSBkcm1fZ2V0X2VkaWQoY29ubmVj dG9yLCBzaWk5MDJ4LT5pMmMtPmFkYXB0ZXIpOworCWVkaWQgPSBkcm1fZ2V0X2VkaWQoY29ubmVj dG9yLCBzaWk5MDJ4LT5pMmNtdXgtPmFkYXB0ZXJbMF0pOwogCWRybV9jb25uZWN0b3JfdXBkYXRl X2VkaWRfcHJvcGVydHkoY29ubmVjdG9yLCBlZGlkKTsKIAlpZiAoZWRpZCkgewogCQludW0gPSBk cm1fYWRkX2VkaWRfbW9kZXMoY29ubmVjdG9yLCBlZGlkKTsKQEAgLTE4MSw0MiArMjY5LDYgQEAg c3RhdGljIGludCBzaWk5MDJ4X2dldF9tb2RlcyhzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29ubmVj dG9yKQogCWlmIChyZXQpCiAJCXJldHVybiByZXQ7CiAKLQkvKgotCSAqIFNvbWV0aW1lcyB0aGUg STJDIGJ1cyBjYW4gc3RhbGwgYWZ0ZXIgZmFpbHVyZSB0byB1c2UgdGhlCi0JICogRURJRCBjaGFu bmVsLiBSZXRyeSBhIGZldyB0aW1lcyB0byBzZWUgaWYgdGhpbmdzIGNsZWFyCi0JICogdXAsIGVs c2UgY29udGludWUgYW55d2F5LgotCSAqLwotCXJldHJpZXMgPSA1OwotCWRvIHsKLQkJcmV0ID0g cmVnbWFwX3JlYWQocmVnbWFwLCBTSUk5MDJYX1NZU19DVFJMX0RBVEEsCi0JCQkJICAmc3RhdHVz KTsKLQkJcmV0cmllcy0tOwotCX0gd2hpbGUgKHJldCAmJiByZXRyaWVzKTsKLQlpZiAocmV0KQot CQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byByZWFkIHN0YXR1cyAoJWQpXG4iLCByZXQpOwotCi0J cmV0ID0gcmVnbWFwX3VwZGF0ZV9iaXRzKHJlZ21hcCwgU0lJOTAyWF9TWVNfQ1RSTF9EQVRBLAot CQkJCSBTSUk5MDJYX1NZU19DVFJMX0REQ19CVVNfUkVRIHwKLQkJCQkgU0lJOTAyWF9TWVNfQ1RS TF9ERENfQlVTX0dSVEQsIDApOwotCWlmIChyZXQpCi0JCXJldHVybiByZXQ7Ci0KLQl0aW1lb3V0 ID0gamlmZmllcyArCi0JCSAgbXNlY3NfdG9famlmZmllcyhTSUk5MDJYX0kyQ19CVVNfQUNRVUlT SVRJT05fVElNRU9VVF9NUyk7Ci0JZG8gewotCQlyZXQgPSByZWdtYXBfcmVhZChyZWdtYXAsIFNJ STkwMlhfU1lTX0NUUkxfREFUQSwgJnN0YXR1cyk7Ci0JCWlmIChyZXQpCi0JCQlyZXR1cm4gcmV0 OwotCX0gd2hpbGUgKHN0YXR1cyAmIChTSUk5MDJYX1NZU19DVFJMX0REQ19CVVNfUkVRIHwKLQkJ CSAgIFNJSTkwMlhfU1lTX0NUUkxfRERDX0JVU19HUlREKSAmJgotCQkgdGltZV9iZWZvcmUoamlm ZmllcywgdGltZW91dCkpOwotCi0JaWYgKHN0YXR1cyAmIChTSUk5MDJYX1NZU19DVFJMX0REQ19C VVNfUkVRIHwKLQkJICAgICAgU0lJOTAyWF9TWVNfQ1RSTF9ERENfQlVTX0dSVEQpKSB7Ci0JCWRl dl9lcnIoZGV2LCAiZmFpbGVkIHRvIHJlbGVhc2UgdGhlIGkyYyBidXNcbiIpOwotCQlyZXR1cm4g LUVUSU1FRE9VVDsKLQl9Ci0KIAlyZXR1cm4gbnVtOwogfQogCkBAIC0yMzcsMjAgKzI4OSwyMCBA QCBzdGF0aWMgdm9pZCBzaWk5MDJ4X2JyaWRnZV9kaXNhYmxlKHN0cnVjdCBkcm1fYnJpZGdlICpi cmlkZ2UpCiB7CiAJc3RydWN0IHNpaTkwMnggKnNpaTkwMnggPSBicmlkZ2VfdG9fc2lpOTAyeChi cmlkZ2UpOwogCi0JcmVnbWFwX3VwZGF0ZV9iaXRzKHNpaTkwMngtPnJlZ21hcCwgU0lJOTAyWF9T WVNfQ1RSTF9EQVRBLAotCQkJICAgU0lJOTAyWF9TWVNfQ1RSTF9QV1JfRFdOLAotCQkJICAgU0lJ OTAyWF9TWVNfQ1RSTF9QV1JfRFdOKTsKKwlzaWk5MDJ4X3VwZGF0ZV9iaXRzKHNpaTkwMngtPmky YywgU0lJOTAyWF9TWVNfQ1RSTF9EQVRBLAorCQkJICAgIFNJSTkwMlhfU1lTX0NUUkxfUFdSX0RX TiwKKwkJCSAgICBTSUk5MDJYX1NZU19DVFJMX1BXUl9EV04pOwogfQogCiBzdGF0aWMgdm9pZCBz aWk5MDJ4X2JyaWRnZV9lbmFibGUoc3RydWN0IGRybV9icmlkZ2UgKmJyaWRnZSkKIHsKIAlzdHJ1 Y3Qgc2lpOTAyeCAqc2lpOTAyeCA9IGJyaWRnZV90b19zaWk5MDJ4KGJyaWRnZSk7CiAKLQlyZWdt YXBfdXBkYXRlX2JpdHMoc2lpOTAyeC0+cmVnbWFwLCBTSUk5MDJYX1BXUl9TVEFURV9DVFJMLAot CQkJICAgU0lJOTAyWF9BVklfUE9XRVJfU1RBVEVfTVNLLAotCQkJICAgU0lJOTAyWF9BVklfUE9X RVJfU1RBVEVfRCgwKSk7Ci0JcmVnbWFwX3VwZGF0ZV9iaXRzKHNpaTkwMngtPnJlZ21hcCwgU0lJ OTAyWF9TWVNfQ1RSTF9EQVRBLAotCQkJICAgU0lJOTAyWF9TWVNfQ1RSTF9QV1JfRFdOLCAwKTsK KwlzaWk5MDJ4X3VwZGF0ZV9iaXRzKHNpaTkwMngtPmkyYywgU0lJOTAyWF9QV1JfU1RBVEVfQ1RS TCwKKwkJCSAgICBTSUk5MDJYX0FWSV9QT1dFUl9TVEFURV9NU0ssCisJCQkgICAgU0lJOTAyWF9B VklfUE9XRVJfU1RBVEVfRCgwKSk7CisJc2lpOTAyeF91cGRhdGVfYml0cyhzaWk5MDJ4LT5pMmMs IFNJSTkwMlhfU1lTX0NUUkxfREFUQSwKKwkJCSAgICBTSUk5MDJYX1NZU19DVFJMX1BXUl9EV04s IDApOwogfQogCiBzdGF0aWMgdm9pZCBzaWk5MDJ4X2JyaWRnZV9tb2RlX3NldChzdHJ1Y3QgZHJt X2JyaWRnZSAqYnJpZGdlLApAQCAtMjU4LDI1ICszMTAsMjUgQEAgc3RhdGljIHZvaWQgc2lpOTAy eF9icmlkZ2VfbW9kZV9zZXQoc3RydWN0IGRybV9icmlkZ2UgKmJyaWRnZSwKIAkJCQkgICAgc3Ry dWN0IGRybV9kaXNwbGF5X21vZGUgKmFkaikKIHsKIAlzdHJ1Y3Qgc2lpOTAyeCAqc2lpOTAyeCA9 IGJyaWRnZV90b19zaWk5MDJ4KGJyaWRnZSk7Ci0Jc3RydWN0IHJlZ21hcCAqcmVnbWFwID0gc2lp OTAyeC0+cmVnbWFwOwotCXU4IGJ1ZltIRE1JX0lORk9GUkFNRV9TSVpFKEFWSSldOworCXU4IGJ1 ZltIRE1JX0lORk9GUkFNRV9TSVpFKEFWSSkgKyAxXTsKIAlzdHJ1Y3QgaGRtaV9hdmlfaW5mb2Zy YW1lIGZyYW1lOwogCWludCByZXQ7CiAKLQlidWZbMF0gPSBhZGotPmNsb2NrOwotCWJ1ZlsxXSA9 IGFkai0+Y2xvY2sgPj4gODsKLQlidWZbMl0gPSBhZGotPnZyZWZyZXNoOwotCWJ1ZlszXSA9IDB4 MDA7Ci0JYnVmWzRdID0gYWRqLT5oZGlzcGxheTsKLQlidWZbNV0gPSBhZGotPmhkaXNwbGF5ID4+ IDg7Ci0JYnVmWzZdID0gYWRqLT52ZGlzcGxheTsKLQlidWZbN10gPSBhZGotPnZkaXNwbGF5ID4+ IDg7Ci0JYnVmWzhdID0gU0lJOTAyWF9UUElfQ0xLX1JBVElPXzFYIHwgU0lJOTAyWF9UUElfQVZJ X1BJWEVMX1JFUF9OT05FIHwKKwlidWZbMF0gPSBTSUk5MDJYX1RQSV9WSURFT19EQVRBOworCWJ1 ZlsxXSA9IGFkai0+Y2xvY2s7CisJYnVmWzJdID0gYWRqLT5jbG9jayA+PiA4OworCWJ1ZlszXSA9 IGFkai0+dnJlZnJlc2g7CisJYnVmWzRdID0gMHgwMDsKKwlidWZbNV0gPSBhZGotPmhkaXNwbGF5 OworCWJ1Zls2XSA9IGFkai0+aGRpc3BsYXkgPj4gODsKKwlidWZbN10gPSBhZGotPnZkaXNwbGF5 OworCWJ1Zls4XSA9IGFkai0+dmRpc3BsYXkgPj4gODsKKwlidWZbOV0gPSBTSUk5MDJYX1RQSV9D TEtfUkFUSU9fMVggfCBTSUk5MDJYX1RQSV9BVklfUElYRUxfUkVQX05PTkUgfAogCQkgU0lJOTAy WF9UUElfQVZJX1BJWEVMX1JFUF9CVVNfMjRCSVQ7Ci0JYnVmWzldID0gU0lJOTAyWF9UUElfQVZJ X0lOUFVUX1JBTkdFX0FVVE8gfAotCQkgU0lJOTAyWF9UUElfQVZJX0lOUFVUX0NPTE9SU1BBQ0Vf UkdCOworCWJ1ZlsxMF0gPSBTSUk5MDJYX1RQSV9BVklfSU5QVVRfUkFOR0VfQVVUTyB8CisJCSAg U0lJOTAyWF9UUElfQVZJX0lOUFVUX0NPTE9SU1BBQ0VfUkdCOwogCi0JcmV0ID0gcmVnbWFwX2J1 bGtfd3JpdGUocmVnbWFwLCBTSUk5MDJYX1RQSV9WSURFT19EQVRBLCBidWYsIDEwKTsKKwlyZXQg PSBzaWk5MDJ4X2J1bGtfd3JpdGUoc2lpOTAyeC0+aTJjLCBidWYsIDExKTsKIAlpZiAocmV0KQog CQlyZXR1cm47CiAKQEAgLTI4NiwxNiArMzM4LDE3IEBAIHN0YXRpYyB2b2lkIHNpaTkwMnhfYnJp ZGdlX21vZGVfc2V0KHN0cnVjdCBkcm1fYnJpZGdlICpicmlkZ2UsCiAJCXJldHVybjsKIAl9CiAK LQlyZXQgPSBoZG1pX2F2aV9pbmZvZnJhbWVfcGFjaygmZnJhbWUsIGJ1Ziwgc2l6ZW9mKGJ1Zikp OworCXJldCA9IGhkbWlfYXZpX2luZm9mcmFtZV9wYWNrKCZmcmFtZSwgYnVmICsgMSwgc2l6ZW9m KGJ1ZikgLSAxKTsKIAlpZiAocmV0IDwgMCkgewogCQlEUk1fRVJST1IoImZhaWxlZCB0byBwYWNr IEFWSSBpbmZvZnJhbWU6ICVkXG4iLCByZXQpOwogCQlyZXR1cm47CiAJfQogCisJYnVmWzBdID0g U0lJOTAyWF9UUElfQVZJX0lORk9GUkFNRTsKIAkvKiBEbyBub3Qgc2VuZCB0aGUgaW5mb2ZyYW1l IGhlYWRlciwgYnV0IGtlZXAgdGhlIENSQyBmaWVsZC4gKi8KLQlyZWdtYXBfYnVsa193cml0ZShy ZWdtYXAsIFNJSTkwMlhfVFBJX0FWSV9JTkZPRlJBTUUsCi0JCQkgIGJ1ZiArIEhETUlfSU5GT0ZS QU1FX0hFQURFUl9TSVpFIC0gMSwKLQkJCSAgSERNSV9BVklfSU5GT0ZSQU1FX1NJWkUgKyAxKTsK KwlzaWk5MDJ4X2J1bGtfd3JpdGUoc2lpOTAyeC0+aTJjLAorCQkJICAgYnVmICsgSERNSV9JTkZP RlJBTUVfSEVBREVSX1NJWkUsCisJCQkgICBIRE1JX0FWSV9JTkZPRlJBTUVfU0laRSArIDEpOwog fQogCiBzdGF0aWMgaW50IHNpaTkwMnhfYnJpZGdlX2F0dGFjaChzdHJ1Y3QgZHJtX2JyaWRnZSAq YnJpZGdlKQpAQCAtMzM2LDI5ICszODksMTMgQEAgc3RhdGljIGNvbnN0IHN0cnVjdCBkcm1fYnJp ZGdlX2Z1bmNzIHNpaTkwMnhfYnJpZGdlX2Z1bmNzID0gewogCS5lbmFibGUgPSBzaWk5MDJ4X2Jy aWRnZV9lbmFibGUsCiB9OwogCi1zdGF0aWMgY29uc3Qgc3RydWN0IHJlZ21hcF9yYW5nZSBzaWk5 MDJ4X3ZvbGF0aWxlX3Jhbmdlc1tdID0gewotCXsgLnJhbmdlX21pbiA9IDAsIC5yYW5nZV9tYXgg PSAweGZmIH0sCi19OwotCi1zdGF0aWMgY29uc3Qgc3RydWN0IHJlZ21hcF9hY2Nlc3NfdGFibGUg c2lpOTAyeF92b2xhdGlsZV90YWJsZSA9IHsKLQkueWVzX3JhbmdlcyA9IHNpaTkwMnhfdm9sYXRp bGVfcmFuZ2VzLAotCS5uX3llc19yYW5nZXMgPSBBUlJBWV9TSVpFKHNpaTkwMnhfdm9sYXRpbGVf cmFuZ2VzKSwKLX07Ci0KLXN0YXRpYyBjb25zdCBzdHJ1Y3QgcmVnbWFwX2NvbmZpZyBzaWk5MDJ4 X3JlZ21hcF9jb25maWcgPSB7Ci0JLnJlZ19iaXRzID0gOCwKLQkudmFsX2JpdHMgPSA4LAotCS52 b2xhdGlsZV90YWJsZSA9ICZzaWk5MDJ4X3ZvbGF0aWxlX3RhYmxlLAotCS5jYWNoZV90eXBlID0g UkVHQ0FDSEVfTk9ORSwKLX07Ci0KIHN0YXRpYyBpcnFyZXR1cm5fdCBzaWk5MDJ4X2ludGVycnVw dChpbnQgaXJxLCB2b2lkICpkYXRhKQogewogCXN0cnVjdCBzaWk5MDJ4ICpzaWk5MDJ4ID0gZGF0 YTsKLQl1bnNpZ25lZCBpbnQgc3RhdHVzID0gMDsKKwl1OCBzdGF0dXMgPSAwOwogCi0JcmVnbWFw X3JlYWQoc2lpOTAyeC0+cmVnbWFwLCBTSUk5MDJYX0lOVF9TVEFUVVMsICZzdGF0dXMpOwotCXJl Z21hcF93cml0ZShzaWk5MDJ4LT5yZWdtYXAsIFNJSTkwMlhfSU5UX1NUQVRVUywgc3RhdHVzKTsK KwlzaWk5MDJ4X3JlYWQoc2lpOTAyeC0+aTJjLCBTSUk5MDJYX0lOVF9TVEFUVVMsICZzdGF0dXMp OworCXNpaTkwMnhfd3JpdGUoc2lpOTAyeC0+aTJjLCBTSUk5MDJYX0lOVF9TVEFUVVMsIHN0YXR1 cyk7CiAKIAlpZiAoKHN0YXR1cyAmIFNJSTkwMlhfSE9UUExVR19FVkVOVCkgJiYgc2lpOTAyeC0+ YnJpZGdlLmRldikKIAkJZHJtX2hlbHBlcl9ocGRfaXJxX2V2ZW50KHNpaTkwMngtPmJyaWRnZS5k ZXYpOwpAQCAtMzY2LDIzICs0MDMsMTExIEBAIHN0YXRpYyBpcnFyZXR1cm5fdCBzaWk5MDJ4X2lu dGVycnVwdChpbnQgaXJxLCB2b2lkICpkYXRhKQogCXJldHVybiBJUlFfSEFORExFRDsKIH0KIAor c3RhdGljIGludCBzaWk5MDJ4X2kyY19ieXBhc3Nfc2VsZWN0KHN0cnVjdCBpMmNfbXV4X2NvcmUg Km11eCwgdTMyIGNoYW5faWQpCit7CisJc3RydWN0IHNpaTkwMnggKnNpaTkwMnggPSBpMmNfbXV4 X3ByaXYobXV4KTsKKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmc2lpOTAyeC0+aTJjLT5kZXY7CisJ dW5zaWduZWQgbG9uZyB0aW1lb3V0OworCXU4IHN0YXR1czsKKwlpbnQgcmV0OworCisJcmV0ID0g X19zaWk5MDJ4X3VwZGF0ZV9iaXRzKHNpaTkwMngtPmkyYywgU0lJOTAyWF9TWVNfQ1RSTF9EQVRB LAorCQkJCSAgICBTSUk5MDJYX1NZU19DVFJMX0REQ19CVVNfUkVRLAorCQkJCSAgICBTSUk5MDJY X1NZU19DVFJMX0REQ19CVVNfUkVRKTsKKworCXRpbWVvdXQgPSBqaWZmaWVzICsKKwkJICBtc2Vj c190b19qaWZmaWVzKFNJSTkwMlhfSTJDX0JVU19BQ1FVSVNJVElPTl9USU1FT1VUX01TKTsKKwlk byB7CisJCXJldCA9IF9fc2lpOTAyeF9yZWFkKHNpaTkwMngtPmkyYywgU0lJOTAyWF9TWVNfQ1RS TF9EQVRBLAorCQkJCSAgICAgJnN0YXR1cyk7CisJCWlmIChyZXQpCisJCQlyZXR1cm4gcmV0Owor CX0gd2hpbGUgKCEoc3RhdHVzICYgU0lJOTAyWF9TWVNfQ1RSTF9ERENfQlVTX0dSVEQpICYmCisJ CSB0aW1lX2JlZm9yZShqaWZmaWVzLCB0aW1lb3V0KSk7CisKKwlpZiAoIShzdGF0dXMgJiBTSUk5 MDJYX1NZU19DVFJMX0REQ19CVVNfR1JURCkpIHsKKwkJZGV2X2VycihkZXYsICJGYWlsZWQgdG8g YWNxdWlyZSB0aGUgaTJjIGJ1c1xuIik7CisJCXJldHVybiAtRVRJTUVET1VUOworCX0KKworCXJl dCA9IF9fc2lpOTAyeF93cml0ZShzaWk5MDJ4LT5pMmMsIFNJSTkwMlhfU1lTX0NUUkxfREFUQSwg c3RhdHVzKTsKKwlpZiAocmV0KQorCQlyZXR1cm4gcmV0OworCXJldHVybiAwOworfQorCitzdGF0 aWMgaW50IHNpaTkwMnhfaTJjX2J5cGFzc19kZXNlbGVjdChzdHJ1Y3QgaTJjX211eF9jb3JlICpt dXgsIHUzMiBjaGFuX2lkKQoreworCXN0cnVjdCBzaWk5MDJ4ICpzaWk5MDJ4ID0gaTJjX211eF9w cml2KG11eCk7CisJc3RydWN0IGRldmljZSAqZGV2ID0gJnNpaTkwMngtPmkyYy0+ZGV2OworCXVu c2lnbmVkIGxvbmcgdGltZW91dDsKKwl1bnNpZ25lZCBpbnQgcmV0cmllczsKKwl1OCBzdGF0dXM7 CisJaW50IHJldDsKKworCXVkZWxheSgzMCk7CisKKwkvKgorCSAqIFNvbWV0aW1lcyB0aGUgSTJD IGJ1cyBjYW4gc3RhbGwgYWZ0ZXIgZmFpbHVyZSB0byB1c2UgdGhlCisJICogRURJRCBjaGFubmVs LiBSZXRyeSBhIGZldyB0aW1lcyB0byBzZWUgaWYgdGhpbmdzIGNsZWFyCisJICogdXAsIGVsc2Ug Y29udGludWUgYW55d2F5LgorCSAqLworCXJldHJpZXMgPSA1OworCWRvIHsKKwkJcmV0ID0gX19z aWk5MDJ4X3JlYWQoc2lpOTAyeC0+aTJjLCBTSUk5MDJYX1NZU19DVFJMX0RBVEEsCisJCQkJICAg ICAmc3RhdHVzKTsKKwkJcmV0cmllcy0tOworCX0gd2hpbGUgKHJldCAmJiByZXRyaWVzKTsKKwlp ZiAocmV0KSB7CisJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIHJlYWQgc3RhdHVzICglZClcbiIs IHJldCk7CisJCXJldHVybiByZXQ7CisJfQorCisJcmV0ID0gX19zaWk5MDJ4X3VwZGF0ZV9iaXRz KHNpaTkwMngtPmkyYywgU0lJOTAyWF9TWVNfQ1RSTF9EQVRBLAorCQkJCSAgICBTSUk5MDJYX1NZ U19DVFJMX0REQ19CVVNfUkVRIHwKKwkJCQkgICAgU0lJOTAyWF9TWVNfQ1RSTF9ERENfQlVTX0dS VEQsIDApOworCWlmIChyZXQpCisJCXJldHVybiByZXQ7CisKKwl0aW1lb3V0ID0gamlmZmllcyAr CisJCSAgbXNlY3NfdG9famlmZmllcyhTSUk5MDJYX0kyQ19CVVNfQUNRVUlTSVRJT05fVElNRU9V VF9NUyk7CisJZG8geworCQlyZXQgPSBfX3NpaTkwMnhfcmVhZChzaWk5MDJ4LT5pMmMsIFNJSTkw MlhfU1lTX0NUUkxfREFUQSwKKwkJCQkgICAgICZzdGF0dXMpOworCQlpZiAocmV0KQorCQkJcmV0 dXJuIHJldDsKKwl9IHdoaWxlIChzdGF0dXMgJiAoU0lJOTAyWF9TWVNfQ1RSTF9ERENfQlVTX1JF USB8CisJCQkgICBTSUk5MDJYX1NZU19DVFJMX0REQ19CVVNfR1JURCkgJiYKKwkJIHRpbWVfYmVm b3JlKGppZmZpZXMsIHRpbWVvdXQpKTsKKworCWlmIChzdGF0dXMgJiAoU0lJOTAyWF9TWVNfQ1RS TF9ERENfQlVTX1JFUSB8CisJCSAgICAgIFNJSTkwMlhfU1lTX0NUUkxfRERDX0JVU19HUlREKSkg eworCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byByZWxlYXNlIHRoZSBpMmMgYnVzXG4iKTsKKwkJ cmV0dXJuIC1FVElNRURPVVQ7CisJfQorCisJcmV0dXJuIDA7Cit9CisKIHN0YXRpYyBpbnQgc2lp OTAyeF9wcm9iZShzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LAogCQkJIGNvbnN0IHN0cnVjdCBp MmNfZGV2aWNlX2lkICppZCkKIHsKIAlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmY2xpZW50LT5kZXY7 Ci0JdW5zaWduZWQgaW50IHN0YXR1cyA9IDA7CiAJc3RydWN0IHNpaTkwMnggKnNpaTkwMng7Ci0J dTggY2hpcGlkWzRdOworCXU4IGNoaXBpZFs0XSwgc3RhdHVzID0gMDsKIAlpbnQgcmV0OwogCisJ cmV0ID0gaTJjX2NoZWNrX2Z1bmN0aW9uYWxpdHkoY2xpZW50LT5hZGFwdGVyLCBJMkNfRlVOQ19J MkMpOworCWlmICghcmV0KSB7CisJCWRldl9lcnIoZGV2LCAiSTJDIGFkYXB0ZXIgbm90IHN1aXRh YmxlXG4iKTsKKwkJcmV0dXJuIC1FSU87CisJfQorCiAJc2lpOTAyeCA9IGRldm1fa3phbGxvYyhk ZXYsIHNpemVvZigqc2lpOTAyeCksIEdGUF9LRVJORUwpOwogCWlmICghc2lpOTAyeCkKIAkJcmV0 dXJuIC1FTk9NRU07CiAKIAlzaWk5MDJ4LT5pMmMgPSBjbGllbnQ7Ci0Jc2lpOTAyeC0+cmVnbWFw ID0gZGV2bV9yZWdtYXBfaW5pdF9pMmMoY2xpZW50LCAmc2lpOTAyeF9yZWdtYXBfY29uZmlnKTsK LQlpZiAoSVNfRVJSKHNpaTkwMngtPnJlZ21hcCkpCi0JCXJldHVybiBQVFJfRVJSKHNpaTkwMngt PnJlZ21hcCk7CiAKIAlzaWk5MDJ4LT5yZXNldF9ncGlvID0gZGV2bV9ncGlvZF9nZXRfb3B0aW9u YWwoZGV2LCAicmVzZXQiLAogCQkJCQkJICAgICAgR1BJT0RfT1VUX0xPVyk7CkBAIC0zOTQsMTQg KzUxOSwxNCBAQCBzdGF0aWMgaW50IHNpaTkwMnhfcHJvYmUoc3RydWN0IGkyY19jbGllbnQgKmNs aWVudCwKIAogCXNpaTkwMnhfcmVzZXQoc2lpOTAyeCk7CiAKLQlyZXQgPSByZWdtYXBfd3JpdGUo c2lpOTAyeC0+cmVnbWFwLCBTSUk5MDJYX1JFR19UUElfUlFCLCAweDApOworCXJldCA9IHNpaTkw Mnhfd3JpdGUoc2lpOTAyeC0+aTJjLCBTSUk5MDJYX1JFR19UUElfUlFCLCAweDApOwogCWlmIChy ZXQpCiAJCXJldHVybiByZXQ7CiAKLQlyZXQgPSByZWdtYXBfYnVsa19yZWFkKHNpaTkwMngtPnJl Z21hcCwgU0lJOTAyWF9SRUdfQ0hJUElEKDApLAotCQkJICAgICAgICZjaGlwaWQsIDQpOworCXJl dCA9IHNpaTkwMnhfYnVsa19yZWFkKHNpaTkwMngtPmkyYywgU0lJOTAyWF9SRUdfQ0hJUElEKDAp LAorCQkJCWNoaXBpZCwgNCk7CiAJaWYgKHJldCkgewotCQlkZXZfZXJyKGRldiwgInJlZ21hcF9y ZWFkIGZhaWxlZCAlZFxuIiwgcmV0KTsKKwkJZGV2X2VycihkZXYsICJDYW4ndCByZWFkIGNoaXBp ZCAoZXJyb3IgPSAlZClcbiIsIHJldCk7CiAJCXJldHVybiByZXQ7CiAJfQogCkBAIC00MTIsMTIg KzUzNywxMiBAQCBzdGF0aWMgaW50IHNpaTkwMnhfcHJvYmUoc3RydWN0IGkyY19jbGllbnQgKmNs aWVudCwKIAl9CiAKIAkvKiBDbGVhciBhbGwgcGVuZGluZyBpbnRlcnJ1cHRzICovCi0JcmVnbWFw X3JlYWQoc2lpOTAyeC0+cmVnbWFwLCBTSUk5MDJYX0lOVF9TVEFUVVMsICZzdGF0dXMpOwotCXJl Z21hcF93cml0ZShzaWk5MDJ4LT5yZWdtYXAsIFNJSTkwMlhfSU5UX1NUQVRVUywgc3RhdHVzKTsK KwlzaWk5MDJ4X3JlYWQoc2lpOTAyeC0+aTJjLCBTSUk5MDJYX0lOVF9TVEFUVVMsICZzdGF0dXMp OworCXNpaTkwMnhfd3JpdGUoc2lpOTAyeC0+aTJjLCBTSUk5MDJYX0lOVF9TVEFUVVMsIHN0YXR1 cyk7CiAKIAlpZiAoY2xpZW50LT5pcnEgPiAwKSB7Ci0JCXJlZ21hcF93cml0ZShzaWk5MDJ4LT5y ZWdtYXAsIFNJSTkwMlhfSU5UX0VOQUJMRSwKLQkJCSAgICAgU0lJOTAyWF9IT1RQTFVHX0VWRU5U KTsKKwkJc2lpOTAyeF93cml0ZShzaWk5MDJ4LT5pMmMsIFNJSTkwMlhfSU5UX0VOQUJMRSwKKwkJ CSAgICAgIFNJSTkwMlhfSE9UUExVR19FVkVOVCk7CiAKIAkJcmV0ID0gZGV2bV9yZXF1ZXN0X3Ro cmVhZGVkX2lycShkZXYsIGNsaWVudC0+aXJxLCBOVUxMLAogCQkJCQkJc2lpOTAyeF9pbnRlcnJ1 cHQsCkBAIC00MzMsNiArNTU4LDIyIEBAIHN0YXRpYyBpbnQgc2lpOTAyeF9wcm9iZShzdHJ1Y3Qg aTJjX2NsaWVudCAqY2xpZW50LAogCiAJaTJjX3NldF9jbGllbnRkYXRhKGNsaWVudCwgc2lpOTAy eCk7CiAKKwlzaWk5MDJ4LT5pMmNtdXggPSBpMmNfbXV4X2FsbG9jKGNsaWVudC0+YWRhcHRlciwg ZGV2LAorCQkJCQkxLCAwLCBJMkNfTVVYX0dBVEUsCisJCQkJCXNpaTkwMnhfaTJjX2J5cGFzc19z ZWxlY3QsCisJCQkJCXNpaTkwMnhfaTJjX2J5cGFzc19kZXNlbGVjdCk7CisJaWYgKCFzaWk5MDJ4 LT5pMmNtdXgpIHsKKwkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gYWxsb2NhdGUgSTJDIG11eFxu Iik7CisJCXJldHVybiAtRU5PTUVNOworCX0KKworCXNpaTkwMngtPmkyY211eC0+cHJpdiA9IHNp aTkwMng7CisJcmV0ID0gaTJjX211eF9hZGRfYWRhcHRlcihzaWk5MDJ4LT5pMmNtdXgsIDAsIDAs IDApOworCWlmIChyZXQpIHsKKwkJZGV2X2VycihkZXYsICJDb3VsZG4ndCBhZGQgaTJjIG11eCBh ZGFwdGVyXG4iKTsKKwkJcmV0dXJuIHJldDsKKwl9CisKIAlyZXR1cm4gMDsKIH0KIApAQCAtNDQx LDYgKzU4Miw5IEBAIHN0YXRpYyBpbnQgc2lpOTAyeF9yZW1vdmUoc3RydWN0IGkyY19jbGllbnQg KmNsaWVudCkKIHsKIAlzdHJ1Y3Qgc2lpOTAyeCAqc2lpOTAyeCA9IGkyY19nZXRfY2xpZW50ZGF0 YShjbGllbnQpOwogCisJaWYgKHNpaTkwMngtPmkyY211eCkKKwkJaTJjX211eF9kZWxfYWRhcHRl cnMoc2lpOTAyeC0+aTJjbXV4KTsKKwogCWRybV9icmlkZ2VfcmVtb3ZlKCZzaWk5MDJ4LT5icmlk Z2UpOwogCiAJcmV0dXJuIDA7Ci0tIAoyLjcuNAoKX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX18KZHJpLWRldmVsIG1haWxpbmcgbGlzdApkcmktZGV2ZWxAbGlz dHMuZnJlZWRlc2t0b3Aub3JnCmh0dHBzOi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4v bGlzdGluZm8vZHJpLWRldmVsCg== From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from relmlor3.renesas.com ([210.160.252.173]:44413 "EHLO relmlie2.idc.renesas.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728930AbeJaVz6 (ORCPT ); Wed, 31 Oct 2018 17:55:58 -0400 From: Fabrizio Castro To: Archit Taneja , Andrzej Hajda , David Airlie , Peter Rosin , Wolfram Sang Cc: Fabrizio Castro , Laurent Pinchart , dri-devel@lists.freedesktop.org, Simon Horman , Geert Uytterhoeven , Chris Paterson , Biju Das , linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, Inki Dae , Boris Brezillon , Linus Walleij Subject: [RFC] drm/bridge/sii902x: Fix EDID readback Date: Wed, 31 Oct 2018 12:57:46 +0000 Message-Id: <1540990667-14109-1-git-send-email-fabrizio.castro@bp.renesas.com> Sender: linux-renesas-soc-owner@vger.kernel.org List-ID: While adding SiI9022A support to the iwg23s board it came up that when the HDMI transmitter is in pass through mode the device is not compliant with the I2C specification anymore, as it requires a far bigger tbuf due to a delay the HDMI transmitter is adding when relaying the STOP condition on the monitor i2c side of things. When not providing an appropriate delay after the STOP condition the i2c bus would get stuck. Also, any other traffic on the bus while talking to the monitor may cause the transaction to fail or even cause issues with the i2c bus as well. I2c-gates seemed to reach consent as a possible way to address these issues, and as such this patch is implementing a solution based on that. Since others are clearly relying on the current implementation of the driver, this patch won't require any DT changes. Since we don't want any interference during the DDC Bus Request/Grant procedure and while talking to the monitor, we have to use the adapter locking primitives rather than the i2c-mux locking primitives, but in order to achieve that I had to get rid of regmap. Signed-off-by: Fabrizio Castro --- Dear All, this is a follow up to: https://www.mail-archive.com/linux-renesas-soc@vger.kernel.org/msg32072.html Comments very welcome! Thanks, Fab drivers/gpu/drm/bridge/sii902x.c | 404 ++++++++++++++++++++++++++------------- 1 file changed, 274 insertions(+), 130 deletions(-) diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c index e59a135..137a05a 100644 --- a/drivers/gpu/drm/bridge/sii902x.c +++ b/drivers/gpu/drm/bridge/sii902x.c @@ -21,9 +21,9 @@ */ #include +#include #include #include -#include #include #include @@ -82,12 +82,130 @@ struct sii902x { struct i2c_client *i2c; - struct regmap *regmap; struct drm_bridge bridge; struct drm_connector connector; struct gpio_desc *reset_gpio; + struct i2c_mux_core *i2cmux; }; +static int sii902x_transfer_read(struct i2c_client *i2c, u8 reg, u8 *val, + u16 len, bool locked) +{ + struct i2c_msg xfer[] = { + { + .addr = i2c->addr, + .flags = 0, + .len = 1, + .buf = ®, + }, { + .addr = i2c->addr, + .flags = I2C_M_RD, + .len = len, + .buf = val, + } + }; + unsigned char xfers = ARRAY_SIZE(xfer); + int ret, retries = 5; + + do { + if (locked) + ret = i2c_transfer(i2c->adapter, xfer, xfers); + else + ret = __i2c_transfer(i2c->adapter, xfer, xfers); + if (ret < 0) + return ret; + } while (ret != xfers && --retries); + return ret == xfers ? 0 : -1; +} + +static int sii902x_bulk_read(struct i2c_client *i2c, u8 reg, u8 *val, u16 len) +{ + return sii902x_transfer_read(i2c, reg, val, len, true); +} + +static int __sii902x_bulk_read(struct i2c_client *i2c, u8 reg, u8 *val, u16 len) +{ + return sii902x_transfer_read(i2c, reg, val, len, false); +} + +static int sii902x_read(struct i2c_client *i2c, u8 reg, u8 *val) +{ + return sii902x_bulk_read(i2c, reg, val, 1); +} + +static int __sii902x_read(struct i2c_client *i2c, u8 reg, u8 *val) +{ + return __sii902x_bulk_read(i2c, reg, val, 1); +} + +static int sii902x_transfer_write(struct i2c_client *i2c, u8 *val, + u16 len, bool locked) +{ + struct i2c_msg xfer = { + .addr = i2c->addr, + .flags = 0, + .len = len, + .buf = val, + }; + int ret, retries = 5; + + do { + if (locked) + ret = i2c_transfer(i2c->adapter, &xfer, 1); + else + ret = __i2c_transfer(i2c->adapter, &xfer, 1); + if (ret < 0) + return ret; + } while (!ret && --retries); + return !ret ? -1 : 0; +} + +static int sii902x_bulk_write(struct i2c_client *i2c, u8 *val, u16 len) +{ + return sii902x_transfer_write(i2c, val, len, true); +} + +static int sii902x_write(struct i2c_client *i2c, u8 reg, u8 val) +{ + u8 data[2] = {reg, val}; + + return sii902x_transfer_write(i2c, data, 2, true); +} + +static int __sii902x_write(struct i2c_client *i2c, u8 reg, u8 val) +{ + u8 data[2] = {reg, val}; + + return sii902x_transfer_write(i2c, data, 2, false); +} + +static int sii902x_update_bits(struct i2c_client *i2c, u8 reg, u8 mask, u8 val) +{ + int ret; + u8 status; + + ret = sii902x_read(i2c, reg, &status); + if (ret) + return ret; + status &= ~mask; + status |= val & mask; + return sii902x_write(i2c, reg, status); +} + +static int __sii902x_update_bits(struct i2c_client *i2c, u8 reg, u8 mask, + u8 val) +{ + int ret; + u8 status; + + ret = __sii902x_read(i2c, reg, &status); + if (ret) + return ret; + status &= ~mask; + status |= val & mask; + return __sii902x_write(i2c, reg, status); +} + static inline struct sii902x *bridge_to_sii902x(struct drm_bridge *bridge) { return container_of(bridge, struct sii902x, bridge); @@ -115,9 +233,9 @@ static enum drm_connector_status sii902x_connector_detect(struct drm_connector *connector, bool force) { struct sii902x *sii902x = connector_to_sii902x(connector); - unsigned int status; + u8 status; - regmap_read(sii902x->regmap, SII902X_INT_STATUS, &status); + sii902x_read(sii902x->i2c, SII902X_INT_STATUS, &status); return (status & SII902X_PLUGGED_STATUS) ? connector_status_connected : connector_status_disconnected; @@ -135,41 +253,11 @@ static const struct drm_connector_funcs sii902x_connector_funcs = { static int sii902x_get_modes(struct drm_connector *connector) { struct sii902x *sii902x = connector_to_sii902x(connector); - struct regmap *regmap = sii902x->regmap; u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24; - struct device *dev = &sii902x->i2c->dev; - unsigned long timeout; - unsigned int retries; - unsigned int status; struct edid *edid; - int num = 0; - int ret; - - ret = regmap_update_bits(regmap, SII902X_SYS_CTRL_DATA, - SII902X_SYS_CTRL_DDC_BUS_REQ, - SII902X_SYS_CTRL_DDC_BUS_REQ); - if (ret) - return ret; + int num = 0, ret; - timeout = jiffies + - msecs_to_jiffies(SII902X_I2C_BUS_ACQUISITION_TIMEOUT_MS); - do { - ret = regmap_read(regmap, SII902X_SYS_CTRL_DATA, &status); - if (ret) - return ret; - } while (!(status & SII902X_SYS_CTRL_DDC_BUS_GRTD) && - time_before(jiffies, timeout)); - - if (!(status & SII902X_SYS_CTRL_DDC_BUS_GRTD)) { - dev_err(dev, "failed to acquire the i2c bus\n"); - return -ETIMEDOUT; - } - - ret = regmap_write(regmap, SII902X_SYS_CTRL_DATA, status); - if (ret) - return ret; - - edid = drm_get_edid(connector, sii902x->i2c->adapter); + edid = drm_get_edid(connector, sii902x->i2cmux->adapter[0]); drm_connector_update_edid_property(connector, edid); if (edid) { num = drm_add_edid_modes(connector, edid); @@ -181,42 +269,6 @@ static int sii902x_get_modes(struct drm_connector *connector) if (ret) return ret; - /* - * Sometimes the I2C bus can stall after failure to use the - * EDID channel. Retry a few times to see if things clear - * up, else continue anyway. - */ - retries = 5; - do { - ret = regmap_read(regmap, SII902X_SYS_CTRL_DATA, - &status); - retries--; - } while (ret && retries); - if (ret) - dev_err(dev, "failed to read status (%d)\n", ret); - - ret = regmap_update_bits(regmap, SII902X_SYS_CTRL_DATA, - SII902X_SYS_CTRL_DDC_BUS_REQ | - SII902X_SYS_CTRL_DDC_BUS_GRTD, 0); - if (ret) - return ret; - - timeout = jiffies + - msecs_to_jiffies(SII902X_I2C_BUS_ACQUISITION_TIMEOUT_MS); - do { - ret = regmap_read(regmap, SII902X_SYS_CTRL_DATA, &status); - if (ret) - return ret; - } while (status & (SII902X_SYS_CTRL_DDC_BUS_REQ | - SII902X_SYS_CTRL_DDC_BUS_GRTD) && - time_before(jiffies, timeout)); - - if (status & (SII902X_SYS_CTRL_DDC_BUS_REQ | - SII902X_SYS_CTRL_DDC_BUS_GRTD)) { - dev_err(dev, "failed to release the i2c bus\n"); - return -ETIMEDOUT; - } - return num; } @@ -237,20 +289,20 @@ static void sii902x_bridge_disable(struct drm_bridge *bridge) { struct sii902x *sii902x = bridge_to_sii902x(bridge); - regmap_update_bits(sii902x->regmap, SII902X_SYS_CTRL_DATA, - SII902X_SYS_CTRL_PWR_DWN, - SII902X_SYS_CTRL_PWR_DWN); + sii902x_update_bits(sii902x->i2c, SII902X_SYS_CTRL_DATA, + SII902X_SYS_CTRL_PWR_DWN, + SII902X_SYS_CTRL_PWR_DWN); } static void sii902x_bridge_enable(struct drm_bridge *bridge) { struct sii902x *sii902x = bridge_to_sii902x(bridge); - regmap_update_bits(sii902x->regmap, SII902X_PWR_STATE_CTRL, - SII902X_AVI_POWER_STATE_MSK, - SII902X_AVI_POWER_STATE_D(0)); - regmap_update_bits(sii902x->regmap, SII902X_SYS_CTRL_DATA, - SII902X_SYS_CTRL_PWR_DWN, 0); + sii902x_update_bits(sii902x->i2c, SII902X_PWR_STATE_CTRL, + SII902X_AVI_POWER_STATE_MSK, + SII902X_AVI_POWER_STATE_D(0)); + sii902x_update_bits(sii902x->i2c, SII902X_SYS_CTRL_DATA, + SII902X_SYS_CTRL_PWR_DWN, 0); } static void sii902x_bridge_mode_set(struct drm_bridge *bridge, @@ -258,25 +310,25 @@ static void sii902x_bridge_mode_set(struct drm_bridge *bridge, struct drm_display_mode *adj) { struct sii902x *sii902x = bridge_to_sii902x(bridge); - struct regmap *regmap = sii902x->regmap; - u8 buf[HDMI_INFOFRAME_SIZE(AVI)]; + u8 buf[HDMI_INFOFRAME_SIZE(AVI) + 1]; struct hdmi_avi_infoframe frame; int ret; - buf[0] = adj->clock; - buf[1] = adj->clock >> 8; - buf[2] = adj->vrefresh; - buf[3] = 0x00; - buf[4] = adj->hdisplay; - buf[5] = adj->hdisplay >> 8; - buf[6] = adj->vdisplay; - buf[7] = adj->vdisplay >> 8; - buf[8] = SII902X_TPI_CLK_RATIO_1X | SII902X_TPI_AVI_PIXEL_REP_NONE | + buf[0] = SII902X_TPI_VIDEO_DATA; + buf[1] = adj->clock; + buf[2] = adj->clock >> 8; + buf[3] = adj->vrefresh; + buf[4] = 0x00; + buf[5] = adj->hdisplay; + buf[6] = adj->hdisplay >> 8; + buf[7] = adj->vdisplay; + buf[8] = adj->vdisplay >> 8; + buf[9] = SII902X_TPI_CLK_RATIO_1X | SII902X_TPI_AVI_PIXEL_REP_NONE | SII902X_TPI_AVI_PIXEL_REP_BUS_24BIT; - buf[9] = SII902X_TPI_AVI_INPUT_RANGE_AUTO | - SII902X_TPI_AVI_INPUT_COLORSPACE_RGB; + buf[10] = SII902X_TPI_AVI_INPUT_RANGE_AUTO | + SII902X_TPI_AVI_INPUT_COLORSPACE_RGB; - ret = regmap_bulk_write(regmap, SII902X_TPI_VIDEO_DATA, buf, 10); + ret = sii902x_bulk_write(sii902x->i2c, buf, 11); if (ret) return; @@ -286,16 +338,17 @@ static void sii902x_bridge_mode_set(struct drm_bridge *bridge, return; } - ret = hdmi_avi_infoframe_pack(&frame, buf, sizeof(buf)); + ret = hdmi_avi_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1); if (ret < 0) { DRM_ERROR("failed to pack AVI infoframe: %d\n", ret); return; } + buf[0] = SII902X_TPI_AVI_INFOFRAME; /* Do not send the infoframe header, but keep the CRC field. */ - regmap_bulk_write(regmap, SII902X_TPI_AVI_INFOFRAME, - buf + HDMI_INFOFRAME_HEADER_SIZE - 1, - HDMI_AVI_INFOFRAME_SIZE + 1); + sii902x_bulk_write(sii902x->i2c, + buf + HDMI_INFOFRAME_HEADER_SIZE, + HDMI_AVI_INFOFRAME_SIZE + 1); } static int sii902x_bridge_attach(struct drm_bridge *bridge) @@ -336,29 +389,13 @@ static const struct drm_bridge_funcs sii902x_bridge_funcs = { .enable = sii902x_bridge_enable, }; -static const struct regmap_range sii902x_volatile_ranges[] = { - { .range_min = 0, .range_max = 0xff }, -}; - -static const struct regmap_access_table sii902x_volatile_table = { - .yes_ranges = sii902x_volatile_ranges, - .n_yes_ranges = ARRAY_SIZE(sii902x_volatile_ranges), -}; - -static const struct regmap_config sii902x_regmap_config = { - .reg_bits = 8, - .val_bits = 8, - .volatile_table = &sii902x_volatile_table, - .cache_type = REGCACHE_NONE, -}; - static irqreturn_t sii902x_interrupt(int irq, void *data) { struct sii902x *sii902x = data; - unsigned int status = 0; + u8 status = 0; - regmap_read(sii902x->regmap, SII902X_INT_STATUS, &status); - regmap_write(sii902x->regmap, SII902X_INT_STATUS, status); + sii902x_read(sii902x->i2c, SII902X_INT_STATUS, &status); + sii902x_write(sii902x->i2c, SII902X_INT_STATUS, status); if ((status & SII902X_HOTPLUG_EVENT) && sii902x->bridge.dev) drm_helper_hpd_irq_event(sii902x->bridge.dev); @@ -366,23 +403,111 @@ static irqreturn_t sii902x_interrupt(int irq, void *data) return IRQ_HANDLED; } +static int sii902x_i2c_bypass_select(struct i2c_mux_core *mux, u32 chan_id) +{ + struct sii902x *sii902x = i2c_mux_priv(mux); + struct device *dev = &sii902x->i2c->dev; + unsigned long timeout; + u8 status; + int ret; + + ret = __sii902x_update_bits(sii902x->i2c, SII902X_SYS_CTRL_DATA, + SII902X_SYS_CTRL_DDC_BUS_REQ, + SII902X_SYS_CTRL_DDC_BUS_REQ); + + timeout = jiffies + + msecs_to_jiffies(SII902X_I2C_BUS_ACQUISITION_TIMEOUT_MS); + do { + ret = __sii902x_read(sii902x->i2c, SII902X_SYS_CTRL_DATA, + &status); + if (ret) + return ret; + } while (!(status & SII902X_SYS_CTRL_DDC_BUS_GRTD) && + time_before(jiffies, timeout)); + + if (!(status & SII902X_SYS_CTRL_DDC_BUS_GRTD)) { + dev_err(dev, "Failed to acquire the i2c bus\n"); + return -ETIMEDOUT; + } + + ret = __sii902x_write(sii902x->i2c, SII902X_SYS_CTRL_DATA, status); + if (ret) + return ret; + return 0; +} + +static int sii902x_i2c_bypass_deselect(struct i2c_mux_core *mux, u32 chan_id) +{ + struct sii902x *sii902x = i2c_mux_priv(mux); + struct device *dev = &sii902x->i2c->dev; + unsigned long timeout; + unsigned int retries; + u8 status; + int ret; + + udelay(30); + + /* + * Sometimes the I2C bus can stall after failure to use the + * EDID channel. Retry a few times to see if things clear + * up, else continue anyway. + */ + retries = 5; + do { + ret = __sii902x_read(sii902x->i2c, SII902X_SYS_CTRL_DATA, + &status); + retries--; + } while (ret && retries); + if (ret) { + dev_err(dev, "failed to read status (%d)\n", ret); + return ret; + } + + ret = __sii902x_update_bits(sii902x->i2c, SII902X_SYS_CTRL_DATA, + SII902X_SYS_CTRL_DDC_BUS_REQ | + SII902X_SYS_CTRL_DDC_BUS_GRTD, 0); + if (ret) + return ret; + + timeout = jiffies + + msecs_to_jiffies(SII902X_I2C_BUS_ACQUISITION_TIMEOUT_MS); + do { + ret = __sii902x_read(sii902x->i2c, SII902X_SYS_CTRL_DATA, + &status); + if (ret) + return ret; + } while (status & (SII902X_SYS_CTRL_DDC_BUS_REQ | + SII902X_SYS_CTRL_DDC_BUS_GRTD) && + time_before(jiffies, timeout)); + + if (status & (SII902X_SYS_CTRL_DDC_BUS_REQ | + SII902X_SYS_CTRL_DDC_BUS_GRTD)) { + dev_err(dev, "failed to release the i2c bus\n"); + return -ETIMEDOUT; + } + + return 0; +} + static int sii902x_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; - unsigned int status = 0; struct sii902x *sii902x; - u8 chipid[4]; + u8 chipid[4], status = 0; int ret; + ret = i2c_check_functionality(client->adapter, I2C_FUNC_I2C); + if (!ret) { + dev_err(dev, "I2C adapter not suitable\n"); + return -EIO; + } + sii902x = devm_kzalloc(dev, sizeof(*sii902x), GFP_KERNEL); if (!sii902x) return -ENOMEM; sii902x->i2c = client; - sii902x->regmap = devm_regmap_init_i2c(client, &sii902x_regmap_config); - if (IS_ERR(sii902x->regmap)) - return PTR_ERR(sii902x->regmap); sii902x->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); @@ -394,14 +519,14 @@ static int sii902x_probe(struct i2c_client *client, sii902x_reset(sii902x); - ret = regmap_write(sii902x->regmap, SII902X_REG_TPI_RQB, 0x0); + ret = sii902x_write(sii902x->i2c, SII902X_REG_TPI_RQB, 0x0); if (ret) return ret; - ret = regmap_bulk_read(sii902x->regmap, SII902X_REG_CHIPID(0), - &chipid, 4); + ret = sii902x_bulk_read(sii902x->i2c, SII902X_REG_CHIPID(0), + chipid, 4); if (ret) { - dev_err(dev, "regmap_read failed %d\n", ret); + dev_err(dev, "Can't read chipid (error = %d)\n", ret); return ret; } @@ -412,12 +537,12 @@ static int sii902x_probe(struct i2c_client *client, } /* Clear all pending interrupts */ - regmap_read(sii902x->regmap, SII902X_INT_STATUS, &status); - regmap_write(sii902x->regmap, SII902X_INT_STATUS, status); + sii902x_read(sii902x->i2c, SII902X_INT_STATUS, &status); + sii902x_write(sii902x->i2c, SII902X_INT_STATUS, status); if (client->irq > 0) { - regmap_write(sii902x->regmap, SII902X_INT_ENABLE, - SII902X_HOTPLUG_EVENT); + sii902x_write(sii902x->i2c, SII902X_INT_ENABLE, + SII902X_HOTPLUG_EVENT); ret = devm_request_threaded_irq(dev, client->irq, NULL, sii902x_interrupt, @@ -433,6 +558,22 @@ static int sii902x_probe(struct i2c_client *client, i2c_set_clientdata(client, sii902x); + sii902x->i2cmux = i2c_mux_alloc(client->adapter, dev, + 1, 0, I2C_MUX_GATE, + sii902x_i2c_bypass_select, + sii902x_i2c_bypass_deselect); + if (!sii902x->i2cmux) { + dev_err(dev, "failed to allocate I2C mux\n"); + return -ENOMEM; + } + + sii902x->i2cmux->priv = sii902x; + ret = i2c_mux_add_adapter(sii902x->i2cmux, 0, 0, 0); + if (ret) { + dev_err(dev, "Couldn't add i2c mux adapter\n"); + return ret; + } + return 0; } @@ -441,6 +582,9 @@ static int sii902x_remove(struct i2c_client *client) { struct sii902x *sii902x = i2c_get_clientdata(client); + if (sii902x->i2cmux) + i2c_mux_del_adapters(sii902x->i2cmux); + drm_bridge_remove(&sii902x->bridge); return 0; -- 2.7.4