From mboxrd@z Thu Jan 1 00:00:00 1970 From: Archit Taneja Subject: Re: [RFC PATCH 3/4] CHROMIUM: drm: bridge: Generic GPIO mux driver Date: Tue, 28 Jun 2016 14:22:34 +0530 Message-ID: <57723AD2.8020806@codeaurora.org> References: <1467013727-11482-1-git-send-email-drinkcat@chromium.org> <1467013727-11482-4-git-send-email-drinkcat@chromium.org> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8"; Format="flowed" Content-Transfer-Encoding: base64 Return-path: Received: from smtp.codeaurora.org (smtp.codeaurora.org [198.145.29.96]) by gabe.freedesktop.org (Postfix) with ESMTPS id C5A486E50A for ; Tue, 28 Jun 2016 08:52:40 +0000 (UTC) In-Reply-To: <1467013727-11482-4-git-send-email-drinkcat@chromium.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Nicolas Boichat , dri-devel@lists.freedesktop.org Cc: Russell King , Thierry Reding , linux-kernel@vger.kernel.org, marcheu@chromium.org List-Id: dri-devel@lists.freedesktop.org CgpPbiAwNi8yNy8yMDE2IDAxOjE4IFBNLCBOaWNvbGFzIEJvaWNoYXQgd3JvdGU6Cj4gVGhpcyBk cml2ZXIgc3VwcG9ydHMgc2luZ2xlIGlucHV0LCAyIG91dHB1dCBkaXNwbGF5IG11eCAoZS5nLgo+ IEhETUkgbXV4KSwgdGhhdCBwcm92aWRlcyBpdHMgc3RhdHVzIHZpYSBhIEdQSU8uCgpUaGlzIG1p Z2h0IG5vdCB3b3JrIGlmIHdlIGhhZCBhIDIgb3IgbW9yZSBicmlkZ2VzIGNvbm5lY3RlZApvbmUg YWZ0ZXIgdGhlIG90aGVyIGF0IHRoZSBvdXRwdXQgcG9ydHMuIEl0IHdvdWxkIGJlIG5pY2VyCmlm IHRoZSBpbnRlcnJ1cHQgaGFuZGxlciBkaXJlY3RseSBtb2RpZmllZCB0aGUgZHJtX2JyaWRnZSdz Cm5leHQgcG9pbnRlciByYXRoZXIgdGhhbiBtYW5hZ2luZyB0aGluZ3MgYnkgaXRzIG93bi4KClRo YXQgYmVpbmcgc2FpZCwgdGhlIGJyaWRnZSBjaGFpbnMgKGJ5IHNldHRpbmcgdGhlIG5leHQKcG9p bnRlcnMpIGFyZW4ndCBleHBlY3RlZCB0byBjaGFuZ2UgYWZ0ZXIgdGhleSBhcmUgc2V0IHVwLgpJ biBvcmRlciB0byB1c2UgbWFrZSB0aGlzIGEgdHJ1bHkgZ2VuZXJpYyBkcml2ZXIsIHdlJ2QKcHJv YmFibHkgbmVlZCB0byBhZGQgc29tZSBzb3J0IG9mIGxvY2tpbmcgZm9yIHRoZSBlbnRpcmUKYnJp ZGdlIGNoYWluIHRvIG1ha2Ugc3VyZSB3ZSBkb24ndCBjaGFuZ2UgdGhpbmdzIGluIHRoZQptaWRk bGUgb2YgYSBtb2Rlc2V0LiBXZSBkb24ndCByZWFsbHkgbmVlZCB0byBhZGQgdGhpcwpmdW5jdGlv bmFsaXR5IHVubGVzcyB0aGVyZSBhcmUgbWFueSBtb3JlIHBsYXRmb3JtcyBsaWtlCnRoZXNlIGhh dmUgbm9uLXN0YXRpYyBtdXhlcyBpbiB0aGUgZGlzcGxheSBjaGFpbi4KCkl0IHdvdWxkIGJlIGJl dHRlciBpZiB0aGlzIGRyaXZlciB3YXMgY29uc2lkZXJlZCB0byBiZQp1c2VkIG9ubHkgZm9yIHRo ZSBtdXggaGFyZHdhcmUgdGhhdCdzIHVzZWQgb24gdGhlIGJvYXJkLgoKQXJjaGl0Cgo+Cj4gU2ln bmVkLW9mZi1ieTogTmljb2xhcyBCb2ljaGF0IDxkcmlua2NhdEBjaHJvbWl1bS5vcmc+Cj4gLS0t Cj4gICBkcml2ZXJzL2dwdS9kcm0vYnJpZGdlL0tjb25maWcgICAgICAgICAgICB8ICAxMSArCj4g ICBkcml2ZXJzL2dwdS9kcm0vYnJpZGdlL01ha2VmaWxlICAgICAgICAgICB8ICAgMSArCj4gICBk cml2ZXJzL2dwdS9kcm0vYnJpZGdlL2dlbmVyaWMtZ3Bpby1tdXguYyB8IDM0NyArKysrKysrKysr KysrKysrKysrKysrKysrKysrKysKPiAgIDMgZmlsZXMgY2hhbmdlZCwgMzU5IGluc2VydGlvbnMo KykKPiAgIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2dwdS9kcm0vYnJpZGdlL2dlbmVyaWMt Z3Bpby1tdXguYwo+Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9icmlkZ2UvS2NvbmZp ZyBiL2RyaXZlcnMvZ3B1L2RybS9icmlkZ2UvS2NvbmZpZwo+IGluZGV4IGRhNDg5ZjAuLmYxZjZm YzYgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9LY29uZmlnCj4gKysrIGIv ZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9LY29uZmlnCj4gQEAgLTQxLDYgKzQxLDE3IEBAIGNvbmZp ZyBEUk1fRFdfSERNSV9BSEJfQVVESU8KPiAgIAkgIERlc2lnbndhcmUgSERNSSBibG9jay4gIFRo aXMgaXMgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoCj4gICAJICB0aGUgaS5NWDYgSERNSSBkcml2 ZXIuCj4KPiArY29uZmlnIERSTV9HRU5FUklDX0dQSU9fTVVYCj4gKwl0cmlzdGF0ZSAiR2VuZXJp YyBHUElPLWNvbnRyb2xsZWQgbXV4Igo+ICsJZGVwZW5kcyBvbiBEUk0KPiArCWRlcGVuZHMgb24g T0YKPiArCXNlbGVjdCBEUk1fS01TX0hFTFBFUgo+ICsJLS0taGVscC0tLQo+ICsJICBUaGlzIGJy aWRnZSBkcml2ZXIgbW9kZWxzIGEgR1BJTy1jb250cm9sbGVkIGRpc3BsYXkgbXV4IHdpdGggb25l Cj4gKwkgIGlucHV0LCAyIG91dHB1dHMgKGUuZy4gYW4gSERNSSBtdXgpLiBUaGUgaGFyZHdhcmUg ZGVjaWRlcyB3aGljaCBvdXRwdXQKPiArCSAgaXMgYWN0aXZlLCByZXBvcnRzIGl0IGFzIGEgR1BJ TywgYW5kIHRoZSBkcml2ZXIgcmVkaXJlY3RzIGNhbGxzIHRvIHRoZQo+ICsJICBhcHByb3ByaWF0 ZSBkb3duc3RyZWFtIGJyaWRnZSAoaWYgYW55KS4KPiArCj4gICBjb25maWcgRFJNX05YUF9QVE4z NDYwCj4gICAJdHJpc3RhdGUgIk5YUCBQVE4zNDYwIERQL0xWRFMgYnJpZGdlIgo+ICAgCWRlcGVu ZHMgb24gT0YKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9NYWtlZmlsZSBi L2RyaXZlcnMvZ3B1L2RybS9icmlkZ2UvTWFrZWZpbGUKPiBpbmRleCA0ODQ2NDY1Li5jYjk3Mjc0 ZmQgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9NYWtlZmlsZQo+ICsrKyBi L2RyaXZlcnMvZ3B1L2RybS9icmlkZ2UvTWFrZWZpbGUKPiBAQCAtNCw2ICs0LDcgQEAgb2JqLSQo Q09ORklHX0RSTV9BTkFMT0dJWF9BTlg3Njg4KSArPSBhbmFsb2dpeC1hbng3Njg4Lm8KPiAgIG9i ai0kKENPTkZJR19EUk1fQU5BTE9HSVhfQU5YNzhYWCkgKz0gYW5hbG9naXgtYW54Nzh4eC5vCj4g ICBvYmotJChDT05GSUdfRFJNX0RXX0hETUkpICs9IGR3LWhkbWkubwo+ICAgb2JqLSQoQ09ORklH X0RSTV9EV19IRE1JX0FIQl9BVURJTykgKz0gZHctaGRtaS1haGItYXVkaW8ubwo+ICtvYmotJChD T05GSUdfRFJNX0dFTkVSSUNfR1BJT19NVVgpICs9IGdlbmVyaWMtZ3Bpby1tdXgubwo+ICAgb2Jq LSQoQ09ORklHX0RSTV9OWFBfUFROMzQ2MCkgKz0gbnhwLXB0bjM0NjAubwo+ICAgb2JqLSQoQ09O RklHX0RSTV9QQVJBREVfUFM4NjIyKSArPSBwYXJhZGUtcHM4NjIyLm8KPiAgIG9iai0kKENPTkZJ R19EUk1fU0lJOTAyWCkgKz0gc2lpOTAyeC5vCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2Ry bS9icmlkZ2UvZ2VuZXJpYy1ncGlvLW11eC5jIGIvZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9nZW5l cmljLWdwaW8tbXV4LmMKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAuLmQz MzY3ZTIKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9nZW5l cmljLWdwaW8tbXV4LmMKPiBAQCAtMCwwICsxLDM0NyBAQAo+ICsvKgo+ICsgKiBBTlg3Njg4IEhE TUktPkRQIGJyaWRnZSBkcml2ZXIKPiArICoKPiArICogQ29weXJpZ2h0IChDKSAyMDE2IEdvb2ds ZSwgSW5jLgo+ICsgKgo+ICsgKiBUaGlzIHNvZnR3YXJlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSB0 ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljCj4gKyAqIExpY2Vuc2UgdmVyc2lvbiAyLCBh cyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgYW5kCj4gKyAqIG1h eSBiZSBjb3BpZWQsIGRpc3RyaWJ1dGVkLCBhbmQgbW9kaWZpZWQgdW5kZXIgdGhvc2UgdGVybXMu Cj4gKyAqCj4gKyAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0 IGl0IHdpbGwgYmUgdXNlZnVsLAo+ICsgKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhv dXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgo+ICsgKiBNRVJDSEFOVEFCSUxJVFkgb3Ig RklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCj4gKyAqIEdOVSBHZW5l cmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCj4gKyAqLwo+ICsKPiArI2luY2x1 ZGUgPGxpbnV4L2dwaW8uaD4KPiArI2luY2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPgo+ICsjaW5j bHVkZSA8bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUu aD4KPiArI2luY2x1ZGUgPGxpbnV4L29mLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9vZl9ncGlvLmg+ Cj4gKyNpbmNsdWRlIDxsaW51eC9vZl9ncmFwaC5oPgo+ICsjaW5jbHVkZSA8ZHJtL2RybV9jcnRj Lmg+Cj4gKyNpbmNsdWRlIDxkcm0vZHJtX2NydGNfaGVscGVyLmg+Cj4gKwo+ICtzdHJ1Y3QgZ3Bp b19kaXNwbGF5X211eCB7Cj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXY7Cj4gKwo+ICsJc3RydWN0IGdw aW9fZGVzYyAqZ3Bpb2RfZGV0ZWN0Owo+ICsJaW50IGRldGVjdF9pcnE7Cj4gKwo+ICsJc3RydWN0 IGRybV9icmlkZ2UgYnJpZGdlOwo+ICsKPiArCXN0cnVjdCBkcm1fYnJpZGdlICpuZXh0WzJdOwo+ ICsKPiArCXN0cnVjdCBtdXRleCBsb2NrOwo+ICsJaW50IGFjdGl2ZTsKPiArCWJvb2wgZW5hYmxl ZDsKPiArfTsKPiArCj4gK3N0YXRpYyBpbmxpbmUgc3RydWN0IGdwaW9fZGlzcGxheV9tdXggKmJy aWRnZV90b19ncGlvX2Rpc3BsYXlfbXV4KAo+ICsJCXN0cnVjdCBkcm1fYnJpZGdlICpicmlkZ2Up Cj4gK3sKPiArCXJldHVybiBjb250YWluZXJfb2YoYnJpZGdlLCBzdHJ1Y3QgZ3Bpb19kaXNwbGF5 X211eCwgYnJpZGdlKTsKPiArfQo+ICsKPiArc3RhdGljIGlycXJldHVybl90IGdwaW9fZGlzcGxh eV9tdXhfZGV0X3RocmVhZGVkX2hhbmRsZXIoaW50IHVudXNlZCwgdm9pZCAqZGF0YSkKPiArewo+ ICsJc3RydWN0IGdwaW9fZGlzcGxheV9tdXggKmdwaW9fZGlzcGxheV9tdXggPSBkYXRhOwo+ICsJ c3RydWN0IGRybV9icmlkZ2UgKm5leHQ7Cj4gKwlpbnQgYWN0aXZlOwo+ICsKPiArCWFjdGl2ZSA9 IGdwaW9kX2dldF92YWx1ZShncGlvX2Rpc3BsYXlfbXV4LT5ncGlvZF9kZXRlY3QpOwo+ICsKPiAr CWRldl9kYmcoZ3Bpb19kaXNwbGF5X211eC0+ZGV2LCAiSW50ZXJydXB0ICVkIVxuIiwgYWN0aXZl KTsKPiArCj4gKwlpZiAoYWN0aXZlID09IGdwaW9fZGlzcGxheV9tdXgtPmFjdGl2ZSkKPiArCQly ZXR1cm4gSVJRX0hBTkRMRUQ7Cj4gKwo+ICsJLyogRGlzYWJsZSBwcmV2aW91cyBicmlkZ2UgKi8K PiArCW11dGV4X2xvY2soJmdwaW9fZGlzcGxheV9tdXgtPmxvY2spOwo+ICsJaWYgKGdwaW9fZGlz cGxheV9tdXgtPmVuYWJsZWQpIHsKPiArCQluZXh0ID0gZ3Bpb19kaXNwbGF5X211eC0+bmV4dFtn cGlvX2Rpc3BsYXlfbXV4LT5hY3RpdmVdOwo+ICsJCWlmIChuZXh0ICYmIG5leHQtPmZ1bmNzLT5k aXNhYmxlKQo+ICsJCQluZXh0LT5mdW5jcy0+ZGlzYWJsZShuZXh0KTsKPiArCX0KPiArCW11dGV4 X3VubG9jaygmZ3Bpb19kaXNwbGF5X211eC0+bG9jayk7Cj4gKwo+ICsJaWYgKGdwaW9fZGlzcGxh eV9tdXgtPmJyaWRnZS5kZXYpCj4gKwkJZHJtX2ttc19oZWxwZXJfaG90cGx1Z19ldmVudChncGlv X2Rpc3BsYXlfbXV4LT5icmlkZ2UuZGV2KTsKPiArCj4gKwkvKiBFbmFibGUgY3VycmVudCBicmlk Z2UgKi8KPiArCW11dGV4X2xvY2soJmdwaW9fZGlzcGxheV9tdXgtPmxvY2spOwo+ICsJaWYgKGdw aW9fZGlzcGxheV9tdXgtPmVuYWJsZWQpIHsKPiArCQluZXh0ID0gZ3Bpb19kaXNwbGF5X211eC0+ bmV4dFthY3RpdmVdOwo+ICsJCWlmIChuZXh0ICYmIG5leHQtPmZ1bmNzLT5lbmFibGUpCj4gKwkJ CW5leHQtPmZ1bmNzLT5lbmFibGUobmV4dCk7Cj4gKwl9Cj4gKwlncGlvX2Rpc3BsYXlfbXV4LT5h Y3RpdmUgPSBhY3RpdmU7Cj4gKwltdXRleF91bmxvY2soJmdwaW9fZGlzcGxheV9tdXgtPmxvY2sp Owo+ICsKPiArCXJldHVybiBJUlFfSEFORExFRDsKPiArfQo+ICsKPiArc3RhdGljIGludCBncGlv X2Rpc3BsYXlfbXV4X2F0dGFjaChzdHJ1Y3QgZHJtX2JyaWRnZSAqYnJpZGdlKQo+ICt7Cj4gKwlz dHJ1Y3QgZ3Bpb19kaXNwbGF5X211eCAqZ3Bpb19kaXNwbGF5X211eCA9Cj4gKwkJCWJyaWRnZV90 b19ncGlvX2Rpc3BsYXlfbXV4KGJyaWRnZSk7Cj4gKwlzdHJ1Y3QgZHJtX2JyaWRnZSAqbmV4dDsK PiArCWludCBpOwo+ICsKPiArCWZvciAoaSA9IDA7IGkgPCBBUlJBWV9TSVpFKGdwaW9fZGlzcGxh eV9tdXgtPm5leHQpOyBpKyspIHsKPiArCQluZXh0ID0gZ3Bpb19kaXNwbGF5X211eC0+bmV4dFtp XTsKPiArCQlpZiAobmV4dCkKPiArCQkJbmV4dC0+ZW5jb2RlciA9IGJyaWRnZS0+ZW5jb2RlcjsK PiArCX0KPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGJvb2wgZ3Bpb19kaXNw bGF5X211eF9tb2RlX2ZpeHVwKHN0cnVjdCBkcm1fYnJpZGdlICpicmlkZ2UsCj4gKwkJCQljb25z dCBzdHJ1Y3QgZHJtX2Rpc3BsYXlfbW9kZSAqbW9kZSwKPiArCQkJCXN0cnVjdCBkcm1fZGlzcGxh eV9tb2RlICphZGp1c3RlZF9tb2RlKQo+ICt7Cj4gKwlzdHJ1Y3QgZ3Bpb19kaXNwbGF5X211eCAq Z3Bpb19kaXNwbGF5X211eCA9Cj4gKwkJYnJpZGdlX3RvX2dwaW9fZGlzcGxheV9tdXgoYnJpZGdl KTsKPiArCXN0cnVjdCBkcm1fYnJpZGdlICpuZXh0Owo+ICsKPiArCW5leHQgPSBncGlvX2Rpc3Bs YXlfbXV4LT5uZXh0W2dwaW9fZGlzcGxheV9tdXgtPmFjdGl2ZV07Cj4gKwo+ICsJaWYgKG5leHQg JiYgbmV4dC0+ZnVuY3MtPm1vZGVfZml4dXApCj4gKwkJcmV0dXJuIG5leHQtPmZ1bmNzLT5tb2Rl X2ZpeHVwKG5leHQsIG1vZGUsIGFkanVzdGVkX21vZGUpOwo+ICsJZWxzZQo+ICsJCXJldHVybiB0 cnVlOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBncGlvX2Rpc3BsYXlfbXV4X21vZGVfc2V0KHN0 cnVjdCBkcm1fYnJpZGdlICpicmlkZ2UsCj4gKwkJCQlzdHJ1Y3QgZHJtX2Rpc3BsYXlfbW9kZSAq bW9kZSwKPiArCQkJCXN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICphZGp1c3RlZF9tb2RlKQo+ICt7 Cj4gKwlzdHJ1Y3QgZ3Bpb19kaXNwbGF5X211eCAqZ3Bpb19kaXNwbGF5X211eCA9Cj4gKwkJYnJp ZGdlX3RvX2dwaW9fZGlzcGxheV9tdXgoYnJpZGdlKTsKPiArCXN0cnVjdCBkcm1fYnJpZGdlICpu ZXh0Owo+ICsKPiArCW5leHQgPSBncGlvX2Rpc3BsYXlfbXV4LT5uZXh0W2dwaW9fZGlzcGxheV9t dXgtPmFjdGl2ZV07Cj4gKwo+ICsJaWYgKG5leHQgJiYgbmV4dC0+ZnVuY3MtPm1vZGVfc2V0KQo+ ICsJCW5leHQtPmZ1bmNzLT5tb2RlX3NldChuZXh0LCBtb2RlLCBhZGp1c3RlZF9tb2RlKTsKPiAr fQo+ICsKPiArc3RhdGljIHZvaWQgZ3Bpb19kaXNwbGF5X211eF9lbmFibGUoc3RydWN0IGRybV9i cmlkZ2UgKmJyaWRnZSkKPiArewo+ICsJc3RydWN0IGdwaW9fZGlzcGxheV9tdXggKmdwaW9fZGlz cGxheV9tdXggPQo+ICsJCWJyaWRnZV90b19ncGlvX2Rpc3BsYXlfbXV4KGJyaWRnZSk7Cj4gKwlz dHJ1Y3QgZHJtX2JyaWRnZSAqbmV4dDsKPiArCj4gKwltdXRleF9sb2NrKCZncGlvX2Rpc3BsYXlf bXV4LT5sb2NrKTsKPiArCj4gKwluZXh0ID0gZ3Bpb19kaXNwbGF5X211eC0+bmV4dFtncGlvX2Rp c3BsYXlfbXV4LT5hY3RpdmVdOwo+ICsJaWYgKG5leHQgJiYgbmV4dC0+ZnVuY3MtPmVuYWJsZSkK PiArCQluZXh0LT5mdW5jcy0+ZW5hYmxlKG5leHQpOwo+ICsKPiArCWdwaW9fZGlzcGxheV9tdXgt PmVuYWJsZWQgPSB0cnVlOwo+ICsKPiArCW11dGV4X3VubG9jaygmZ3Bpb19kaXNwbGF5X211eC0+ bG9jayk7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIGdwaW9fZGlzcGxheV9tdXhfZGlzYWJsZShz dHJ1Y3QgZHJtX2JyaWRnZSAqYnJpZGdlKQo+ICt7Cj4gKwlzdHJ1Y3QgZ3Bpb19kaXNwbGF5X211 eCAqZ3Bpb19kaXNwbGF5X211eCA9Cj4gKwkJYnJpZGdlX3RvX2dwaW9fZGlzcGxheV9tdXgoYnJp ZGdlKTsKPiArCXN0cnVjdCBkcm1fYnJpZGdlICpuZXh0Owo+ICsKPiArCW11dGV4X2xvY2soJmdw aW9fZGlzcGxheV9tdXgtPmxvY2spOwo+ICsKPiArCW5leHQgPSBncGlvX2Rpc3BsYXlfbXV4LT5u ZXh0W2dwaW9fZGlzcGxheV9tdXgtPmFjdGl2ZV07Cj4gKwlpZiAobmV4dCAmJiBuZXh0LT5mdW5j cy0+ZGlzYWJsZSkKPiArCQluZXh0LT5mdW5jcy0+ZGlzYWJsZShuZXh0KTsKPiArCj4gKwlncGlv X2Rpc3BsYXlfbXV4LT5lbmFibGVkID0gZmFsc2U7Cj4gKwo+ICsJbXV0ZXhfdW5sb2NrKCZncGlv X2Rpc3BsYXlfbXV4LT5sb2NrKTsKPiArfQo+ICsKPiArLyoqCj4gKyAqIFNpbmNlIHRoaXMgZHJp dmVyIF9yZWFjdHNfIHRvIG11eCBjaGFuZ2VzLCB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSBhbGwKPiAr ICogZG93bnN0cmVhbSBicmlkZ2VzIGFyZSBwcmUtZW5hYmxlZC4KPiArICovCj4gK3N0YXRpYyB2 b2lkIGdwaW9fZGlzcGxheV9tdXhfcHJlX2VuYWJsZShzdHJ1Y3QgZHJtX2JyaWRnZSAqYnJpZGdl KQo+ICt7Cj4gKwlzdHJ1Y3QgZ3Bpb19kaXNwbGF5X211eCAqZ3Bpb19kaXNwbGF5X211eCA9Cj4g KwkJYnJpZGdlX3RvX2dwaW9fZGlzcGxheV9tdXgoYnJpZGdlKTsKPiArCXN0cnVjdCBkcm1fYnJp ZGdlICpuZXh0Owo+ICsJaW50IGk7Cj4gKwo+ICsJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUo Z3Bpb19kaXNwbGF5X211eC0+bmV4dCk7IGkrKykgewo+ICsJCW5leHQgPSBncGlvX2Rpc3BsYXlf bXV4LT5uZXh0W2ldOwo+ICsJCWlmIChuZXh0ICYmIG5leHQtPmZ1bmNzLT5wcmVfZW5hYmxlKQo+ ICsJCQluZXh0LT5mdW5jcy0+cHJlX2VuYWJsZShuZXh0KTsKPiArCX0KPiArfQo+ICsKPiArc3Rh dGljIHZvaWQgZ3Bpb19kaXNwbGF5X211eF9wb3N0X2Rpc2FibGUoc3RydWN0IGRybV9icmlkZ2Ug KmJyaWRnZSkKPiArewo+ICsJc3RydWN0IGdwaW9fZGlzcGxheV9tdXggKmdwaW9fZGlzcGxheV9t dXggPQo+ICsJCWJyaWRnZV90b19ncGlvX2Rpc3BsYXlfbXV4KGJyaWRnZSk7Cj4gKwlzdHJ1Y3Qg ZHJtX2JyaWRnZSAqbmV4dDsKPiArCWludCBpOwo+ICsKPiArCWZvciAoaSA9IDA7IGkgPCBBUlJB WV9TSVpFKGdwaW9fZGlzcGxheV9tdXgtPm5leHQpOyBpKyspIHsKPiArCQluZXh0ID0gZ3Bpb19k aXNwbGF5X211eC0+bmV4dFtpXTsKPiArCQlpZiAobmV4dCAmJiBuZXh0LT5mdW5jcy0+cG9zdF9k aXNhYmxlKQo+ICsJCQluZXh0LT5mdW5jcy0+cG9zdF9kaXNhYmxlKG5leHQpOwo+ICsJfQo+ICt9 Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGRybV9icmlkZ2VfZnVuY3MgZ3Bpb19kaXNwbGF5 X211eF9icmlkZ2VfZnVuY3MgPSB7Cj4gKwkuYXR0YWNoID0gZ3Bpb19kaXNwbGF5X211eF9hdHRh Y2gsCj4gKwkubW9kZV9maXh1cCA9IGdwaW9fZGlzcGxheV9tdXhfbW9kZV9maXh1cCwKPiArCS5k aXNhYmxlID0gZ3Bpb19kaXNwbGF5X211eF9kaXNhYmxlLAo+ICsJLnBvc3RfZGlzYWJsZSA9IGdw aW9fZGlzcGxheV9tdXhfcG9zdF9kaXNhYmxlLAo+ICsJLm1vZGVfc2V0ID0gZ3Bpb19kaXNwbGF5 X211eF9tb2RlX3NldCwKPiArCS5wcmVfZW5hYmxlID0gZ3Bpb19kaXNwbGF5X211eF9wcmVfZW5h YmxlLAo+ICsJLmVuYWJsZSA9IGdwaW9fZGlzcGxheV9tdXhfZW5hYmxlLAo+ICt9Owo+ICsKPiAr c3RhdGljIGludCBncGlvX2Rpc3BsYXlfbXV4X3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2Ug KnBkZXYpCj4gK3sKPiArCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZwZGV2LT5kZXY7Cj4gKwlzdHJ1 Y3QgZ3Bpb19kaXNwbGF5X211eCAqZ3Bpb19kaXNwbGF5X211eDsKPiArCXN0cnVjdCBkZXZpY2Vf bm9kZSAqcG9ydCwgKmVwLCAqcmVtb3RlOwo+ICsJaW50IHJldDsKPiArCXUzMiByZWc7Cj4gKwo+ ICsJZ3Bpb19kaXNwbGF5X211eCA9IGRldm1fa3phbGxvYyhkZXYsIHNpemVvZigqZ3Bpb19kaXNw bGF5X211eCksCj4gKwkJCQkJR0ZQX0tFUk5FTCk7Cj4gKwlpZiAoIWdwaW9fZGlzcGxheV9tdXgp Cj4gKwkJcmV0dXJuIC1FTk9NRU07Cj4gKwo+ICsJbXV0ZXhfaW5pdCgmZ3Bpb19kaXNwbGF5X211 eC0+bG9jayk7Cj4gKwo+ICsJcGxhdGZvcm1fc2V0X2RydmRhdGEocGRldiwgZ3Bpb19kaXNwbGF5 X211eCk7Cj4gKwlncGlvX2Rpc3BsYXlfbXV4LT5kZXYgPSAmcGRldi0+ZGV2Owo+ICsKPiArCWdw aW9fZGlzcGxheV9tdXgtPmJyaWRnZS5vZl9ub2RlID0gZGV2LT5vZl9ub2RlOwo+ICsKPiArCWdw aW9fZGlzcGxheV9tdXgtPmdwaW9kX2RldGVjdCA9Cj4gKwkJZGV2bV9ncGlvZF9nZXQoZGV2LCAi ZGV0ZWN0IiwgR1BJT0RfSU4pOwo+ICsJaWYgKElTX0VSUihncGlvX2Rpc3BsYXlfbXV4LT5ncGlv ZF9kZXRlY3QpKQo+ICsJCXJldHVybiBQVFJfRVJSKGdwaW9fZGlzcGxheV9tdXgtPmdwaW9kX2Rl dGVjdCk7Cj4gKwo+ICsJZ3Bpb19kaXNwbGF5X211eC0+ZGV0ZWN0X2lycSA9Cj4gKwkJZ3Bpb2Rf dG9faXJxKGdwaW9fZGlzcGxheV9tdXgtPmdwaW9kX2RldGVjdCk7Cj4gKwlpZiAoZ3Bpb19kaXNw bGF5X211eC0+ZGV0ZWN0X2lycSA8IDApIHsKPiArCQlkZXZfZXJyKGRldiwgIkZhaWxlZCB0byBn ZXQgb3V0cHV0IGlycSAlZFxuIiwKPiArCQkJZ3Bpb19kaXNwbGF5X211eC0+ZGV0ZWN0X2lycSk7 Cj4gKwkJcmV0dXJuIC1FTk9ERVY7Cj4gKwl9Cj4gKwo+ICsJcG9ydCA9IG9mX2dyYXBoX2dldF9w b3J0X2J5X2lkKGRldi0+b2Zfbm9kZSwgMSk7Cj4gKwlpZiAoIXBvcnQpIHsKPiArCQlkZXZfZXJy KGRldiwgIk1pc3Npbmcgb3V0cHV0IHBvcnQgbm9kZVxuIik7Cj4gKwkJcmV0dXJuIC1FSU5WQUw7 Cj4gKwl9Cj4gKwo+ICsJZm9yX2VhY2hfY2hpbGRfb2Zfbm9kZShwb3J0LCBlcCkgewo+ICsJCWlm ICghZXAtPm5hbWUgfHwgKG9mX25vZGVfY21wKGVwLT5uYW1lLCAiZW5kcG9pbnQiKSAhPSAwKSkg ewo+ICsJCQlvZl9ub2RlX3B1dChlcCk7Cj4gKwkJCWNvbnRpbnVlOwo+ICsJCX0KPiArCj4gKwkJ aWYgKG9mX3Byb3BlcnR5X3JlYWRfdTMyKGVwLCAicmVnIiwgJnJlZykgPCAwIHx8Cj4gKwkJCQly ZWcgPj0gQVJSQVlfU0laRShncGlvX2Rpc3BsYXlfbXV4LT5uZXh0KSkgewo+ICsJCQlkZXZfZXJy KGRldiwKPiArCQkJICAgICJNaXNzaW5nL2ludmFsaWQgcmVnIHByb3BlcnR5IGZvciBlbmRwb2lu dCAlc1xuIiwKPiArCQkJCWVwLT5mdWxsX25hbWUpOwo+ICsJCQlvZl9ub2RlX3B1dChlcCk7Cj4g KwkJCW9mX25vZGVfcHV0KHBvcnQpOwo+ICsJCQlyZXR1cm4gLUVJTlZBTDsKPiArCQl9Cj4gKwo+ ICsJCXJlbW90ZSA9IG9mX2dyYXBoX2dldF9yZW1vdGVfcG9ydF9wYXJlbnQoZXApOwo+ICsJCWlm ICghcmVtb3RlKSB7Cj4gKwkJCWRldl9lcnIoZGV2LAo+ICsJCQkgICAgIk1pc3NpbmcgY29ubmVj dG9yL2JyaWRnZSBub2RlIGZvciBlbmRwb2ludCAlc1xuIiwKPiArCQkJCWVwLT5mdWxsX25hbWUp Owo+ICsJCQlvZl9ub2RlX3B1dChlcCk7Cj4gKwkJCW9mX25vZGVfcHV0KHBvcnQpOwo+ICsJCQly ZXR1cm4gLUVJTlZBTDsKPiArCQl9Cj4gKwkJb2Zfbm9kZV9wdXQoZXApOwo+ICsKPiArCQlpZiAo b2ZfZGV2aWNlX2lzX2NvbXBhdGlibGUocmVtb3RlLCAiaGRtaS1jb25uZWN0b3IiKSkgewo+ICsJ CQlvZl9ub2RlX3B1dChyZW1vdGUpOwo+ICsJCQljb250aW51ZTsKPiArCQl9Cj4gKwo+ICsJCWdw aW9fZGlzcGxheV9tdXgtPm5leHRbcmVnXSA9IG9mX2RybV9maW5kX2JyaWRnZShyZW1vdGUpOwo+ ICsJCWlmICghZ3Bpb19kaXNwbGF5X211eC0+bmV4dFtyZWddKSB7Cj4gKwkJCWRldl9lcnIoZGV2 LCAiV2FpdGluZyBmb3IgZXh0ZXJuYWwgYnJpZGdlICVzXG4iLAo+ICsJCQkJcmVtb3RlLT5uYW1l KTsKPiArCQkJb2Zfbm9kZV9wdXQocmVtb3RlKTsKPiArCQkJb2Zfbm9kZV9wdXQocG9ydCk7Cj4g KwkJCXJldHVybiAtRVBST0JFX0RFRkVSOwo+ICsJCX0KPiArCj4gKwkJb2Zfbm9kZV9wdXQocmVt b3RlKTsKPiArCX0KPiArCW9mX25vZGVfcHV0KHBvcnQpOwo+ICsKPiArCWdwaW9fZGlzcGxheV9t dXgtPmJyaWRnZS5mdW5jcyA9ICZncGlvX2Rpc3BsYXlfbXV4X2JyaWRnZV9mdW5jczsKPiArCXJl dCA9IGRybV9icmlkZ2VfYWRkKCZncGlvX2Rpc3BsYXlfbXV4LT5icmlkZ2UpOwo+ICsJaWYgKHJl dCA8IDApIHsKPiArCQlkZXZfZXJyKGRldiwgIkZhaWxlZCB0byBhZGQgZHJtIGJyaWRnZVxuIik7 Cj4gKwkJcmV0dXJuIHJldDsKPiArCX0KPiArCj4gKwlyZXQgPSBkZXZtX3JlcXVlc3RfdGhyZWFk ZWRfaXJxKGRldiwgZ3Bpb19kaXNwbGF5X211eC0+ZGV0ZWN0X2lycSwKPiArCQkJCU5VTEwsCj4g KwkJCQlncGlvX2Rpc3BsYXlfbXV4X2RldF90aHJlYWRlZF9oYW5kbGVyLAo+ICsJCQkJSVJRRl9U UklHR0VSX1JJU0lORyB8IElSUUZfVFJJR0dFUl9GQUxMSU5HIHwKPiArCQkJCQlJUlFGX09ORVNI T1QsCj4gKwkJCQkiZ3Bpby1kaXNwbGF5LW11eC1kZXQiLCBncGlvX2Rpc3BsYXlfbXV4KTsKPiAr CWlmIChyZXQpIHsKPiArCQlkZXZfZXJyKGRldiwgIkZhaWxlZCB0byByZXF1ZXN0IE1VWF9ERVQg dGhyZWFkZWQgaXJxXG4iKTsKPiArCQlnb3RvIGVycl9icmlkZ2VfcmVtb3ZlOwo+ICsJfQo+ICsK PiArCWdwaW9fZGlzcGxheV9tdXgtPmFjdGl2ZSA9Cj4gKwkJCWdwaW9kX2dldF92YWx1ZShncGlv X2Rpc3BsYXlfbXV4LT5ncGlvZF9kZXRlY3QpOwo+ICsKPiArCXJldHVybiAwOwo+ICsKPiArZXJy X2JyaWRnZV9yZW1vdmU6Cj4gKwlkcm1fYnJpZGdlX3JlbW92ZSgmZ3Bpb19kaXNwbGF5X211eC0+ YnJpZGdlKTsKPiArCj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGdwaW9f ZGlzcGxheV9tdXhfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCj4gK3sKPiAr CXN0cnVjdCBncGlvX2Rpc3BsYXlfbXV4ICpncGlvX2Rpc3BsYXlfbXV4ID0gcGxhdGZvcm1fZ2V0 X2RydmRhdGEocGRldik7Cj4gKwo+ICsJZHJtX2JyaWRnZV9yZW1vdmUoJmdwaW9fZGlzcGxheV9t dXgtPmJyaWRnZSk7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBjb25zdCBz dHJ1Y3Qgb2ZfZGV2aWNlX2lkIGdwaW9fZGlzcGxheV9tdXhfbWF0Y2hbXSA9IHsKPiArCXsgLmNv bXBhdGlibGUgPSAiZ3Bpby1kaXNwbGF5LW11eCIsIH0sCj4gKwl7fSwKPiArfTsKPiArCj4gK3N0 cnVjdCBwbGF0Zm9ybV9kcml2ZXIgZ3Bpb19kaXNwbGF5X211eF9kcml2ZXIgPSB7Cj4gKwkucHJv YmUgPSBncGlvX2Rpc3BsYXlfbXV4X3Byb2JlLAo+ICsJLnJlbW92ZSA9IGdwaW9fZGlzcGxheV9t dXhfcmVtb3ZlLAo+ICsJLmRyaXZlciA9IHsKPiArCQkubmFtZSA9ICJncGlvLWRpc3BsYXktbXV4 IiwKPiArCQkub2ZfbWF0Y2hfdGFibGUgPSBncGlvX2Rpc3BsYXlfbXV4X21hdGNoLAo+ICsJfSwK PiArfTsKPiArCj4gK21vZHVsZV9wbGF0Zm9ybV9kcml2ZXIoZ3Bpb19kaXNwbGF5X211eF9kcml2 ZXIpOwo+ICsKPiArTU9EVUxFX0RFU0NSSVBUSU9OKCJHUElPLWNvbnRyb2xsZWQgZGlzcGxheSBt dXgiKTsKPiArTU9EVUxFX0FVVEhPUigiTmljb2xhcyBCb2ljaGF0IDxkcmlua2NhdEBjaHJvbWl1 bS5vcmc+Iik7Cj4gK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsKPgoKLS0gClF1YWxjb21tIElu bm92YXRpb24gQ2VudGVyLCBJbmMuIGlzIGEgbWVtYmVyIG9mIENvZGUgQXVyb3JhIEZvcnVtLAph IExpbnV4IEZvdW5kYXRpb24gQ29sbGFib3JhdGl2ZSBQcm9qZWN0Cl9fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmRyaS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJp LWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9y Zy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo= From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752516AbcF1Iwo (ORCPT ); Tue, 28 Jun 2016 04:52:44 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:36006 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751770AbcF1Iwl (ORCPT ); Tue, 28 Jun 2016 04:52:41 -0400 Subject: Re: [RFC PATCH 3/4] CHROMIUM: drm: bridge: Generic GPIO mux driver To: Nicolas Boichat , dri-devel@lists.freedesktop.org References: <1467013727-11482-1-git-send-email-drinkcat@chromium.org> <1467013727-11482-4-git-send-email-drinkcat@chromium.org> Cc: Thierry Reding , Russell King , linux-kernel@vger.kernel.org, p.zabel@pengutronix.de, marcheu@chromium.org From: Archit Taneja Message-ID: <57723AD2.8020806@codeaurora.org> Date: Tue, 28 Jun 2016 14:22:34 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.8.0 MIME-Version: 1.0 In-Reply-To: <1467013727-11482-4-git-send-email-drinkcat@chromium.org> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 06/27/2016 01:18 PM, Nicolas Boichat wrote: > This driver supports single input, 2 output display mux (e.g. > HDMI mux), that provides its status via a GPIO. This might not work if we had a 2 or more bridges connected one after the other at the output ports. It would be nicer if the interrupt handler directly modified the drm_bridge's next pointer rather than managing things by its own. That being said, the bridge chains (by setting the next pointers) aren't expected to change after they are set up. In order to use make this a truly generic driver, we'd probably need to add some sort of locking for the entire bridge chain to make sure we don't change things in the middle of a modeset. We don't really need to add this functionality unless there are many more platforms like these have non-static muxes in the display chain. It would be better if this driver was considered to be used only for the mux hardware that's used on the board. Archit > > Signed-off-by: Nicolas Boichat > --- > drivers/gpu/drm/bridge/Kconfig | 11 + > drivers/gpu/drm/bridge/Makefile | 1 + > drivers/gpu/drm/bridge/generic-gpio-mux.c | 347 ++++++++++++++++++++++++++++++ > 3 files changed, 359 insertions(+) > create mode 100644 drivers/gpu/drm/bridge/generic-gpio-mux.c > > diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig > index da489f0..f1f6fc6 100644 > --- a/drivers/gpu/drm/bridge/Kconfig > +++ b/drivers/gpu/drm/bridge/Kconfig > @@ -41,6 +41,17 @@ config DRM_DW_HDMI_AHB_AUDIO > Designware HDMI block. This is used in conjunction with > the i.MX6 HDMI driver. > > +config DRM_GENERIC_GPIO_MUX > + tristate "Generic GPIO-controlled mux" > + depends on DRM > + depends on OF > + select DRM_KMS_HELPER > + ---help--- > + This bridge driver models a GPIO-controlled display mux with one > + input, 2 outputs (e.g. an HDMI mux). The hardware decides which output > + is active, reports it as a GPIO, and the driver redirects calls to the > + appropriate downstream bridge (if any). > + > config DRM_NXP_PTN3460 > tristate "NXP PTN3460 DP/LVDS bridge" > depends on OF > diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile > index 4846465..cb97274fd 100644 > --- a/drivers/gpu/drm/bridge/Makefile > +++ b/drivers/gpu/drm/bridge/Makefile > @@ -4,6 +4,7 @@ obj-$(CONFIG_DRM_ANALOGIX_ANX7688) += analogix-anx7688.o > obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o > obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o > obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o > +obj-$(CONFIG_DRM_GENERIC_GPIO_MUX) += generic-gpio-mux.o > obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o > obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o > obj-$(CONFIG_DRM_SII902X) += sii902x.o > diff --git a/drivers/gpu/drm/bridge/generic-gpio-mux.c b/drivers/gpu/drm/bridge/generic-gpio-mux.c > new file mode 100644 > index 0000000..d3367e2 > --- /dev/null > +++ b/drivers/gpu/drm/bridge/generic-gpio-mux.c > @@ -0,0 +1,347 @@ > +/* > + * ANX7688 HDMI->DP bridge driver > + * > + * Copyright (C) 2016 Google, Inc. > + * > + * This software is licensed under the terms of the GNU General Public > + * License version 2, as published by the Free Software Foundation, and > + * may be copied, distributed, and modified under those terms. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +struct gpio_display_mux { > + struct device *dev; > + > + struct gpio_desc *gpiod_detect; > + int detect_irq; > + > + struct drm_bridge bridge; > + > + struct drm_bridge *next[2]; > + > + struct mutex lock; > + int active; > + bool enabled; > +}; > + > +static inline struct gpio_display_mux *bridge_to_gpio_display_mux( > + struct drm_bridge *bridge) > +{ > + return container_of(bridge, struct gpio_display_mux, bridge); > +} > + > +static irqreturn_t gpio_display_mux_det_threaded_handler(int unused, void *data) > +{ > + struct gpio_display_mux *gpio_display_mux = data; > + struct drm_bridge *next; > + int active; > + > + active = gpiod_get_value(gpio_display_mux->gpiod_detect); > + > + dev_dbg(gpio_display_mux->dev, "Interrupt %d!\n", active); > + > + if (active == gpio_display_mux->active) > + return IRQ_HANDLED; > + > + /* Disable previous bridge */ > + mutex_lock(&gpio_display_mux->lock); > + if (gpio_display_mux->enabled) { > + next = gpio_display_mux->next[gpio_display_mux->active]; > + if (next && next->funcs->disable) > + next->funcs->disable(next); > + } > + mutex_unlock(&gpio_display_mux->lock); > + > + if (gpio_display_mux->bridge.dev) > + drm_kms_helper_hotplug_event(gpio_display_mux->bridge.dev); > + > + /* Enable current bridge */ > + mutex_lock(&gpio_display_mux->lock); > + if (gpio_display_mux->enabled) { > + next = gpio_display_mux->next[active]; > + if (next && next->funcs->enable) > + next->funcs->enable(next); > + } > + gpio_display_mux->active = active; > + mutex_unlock(&gpio_display_mux->lock); > + > + return IRQ_HANDLED; > +} > + > +static int gpio_display_mux_attach(struct drm_bridge *bridge) > +{ > + struct gpio_display_mux *gpio_display_mux = > + bridge_to_gpio_display_mux(bridge); > + struct drm_bridge *next; > + int i; > + > + for (i = 0; i < ARRAY_SIZE(gpio_display_mux->next); i++) { > + next = gpio_display_mux->next[i]; > + if (next) > + next->encoder = bridge->encoder; > + } > + > + return 0; > +} > + > +static bool gpio_display_mux_mode_fixup(struct drm_bridge *bridge, > + const struct drm_display_mode *mode, > + struct drm_display_mode *adjusted_mode) > +{ > + struct gpio_display_mux *gpio_display_mux = > + bridge_to_gpio_display_mux(bridge); > + struct drm_bridge *next; > + > + next = gpio_display_mux->next[gpio_display_mux->active]; > + > + if (next && next->funcs->mode_fixup) > + return next->funcs->mode_fixup(next, mode, adjusted_mode); > + else > + return true; > +} > + > +static void gpio_display_mux_mode_set(struct drm_bridge *bridge, > + struct drm_display_mode *mode, > + struct drm_display_mode *adjusted_mode) > +{ > + struct gpio_display_mux *gpio_display_mux = > + bridge_to_gpio_display_mux(bridge); > + struct drm_bridge *next; > + > + next = gpio_display_mux->next[gpio_display_mux->active]; > + > + if (next && next->funcs->mode_set) > + next->funcs->mode_set(next, mode, adjusted_mode); > +} > + > +static void gpio_display_mux_enable(struct drm_bridge *bridge) > +{ > + struct gpio_display_mux *gpio_display_mux = > + bridge_to_gpio_display_mux(bridge); > + struct drm_bridge *next; > + > + mutex_lock(&gpio_display_mux->lock); > + > + next = gpio_display_mux->next[gpio_display_mux->active]; > + if (next && next->funcs->enable) > + next->funcs->enable(next); > + > + gpio_display_mux->enabled = true; > + > + mutex_unlock(&gpio_display_mux->lock); > +} > + > +static void gpio_display_mux_disable(struct drm_bridge *bridge) > +{ > + struct gpio_display_mux *gpio_display_mux = > + bridge_to_gpio_display_mux(bridge); > + struct drm_bridge *next; > + > + mutex_lock(&gpio_display_mux->lock); > + > + next = gpio_display_mux->next[gpio_display_mux->active]; > + if (next && next->funcs->disable) > + next->funcs->disable(next); > + > + gpio_display_mux->enabled = false; > + > + mutex_unlock(&gpio_display_mux->lock); > +} > + > +/** > + * Since this driver _reacts_ to mux changes, we need to make sure all > + * downstream bridges are pre-enabled. > + */ > +static void gpio_display_mux_pre_enable(struct drm_bridge *bridge) > +{ > + struct gpio_display_mux *gpio_display_mux = > + bridge_to_gpio_display_mux(bridge); > + struct drm_bridge *next; > + int i; > + > + for (i = 0; i < ARRAY_SIZE(gpio_display_mux->next); i++) { > + next = gpio_display_mux->next[i]; > + if (next && next->funcs->pre_enable) > + next->funcs->pre_enable(next); > + } > +} > + > +static void gpio_display_mux_post_disable(struct drm_bridge *bridge) > +{ > + struct gpio_display_mux *gpio_display_mux = > + bridge_to_gpio_display_mux(bridge); > + struct drm_bridge *next; > + int i; > + > + for (i = 0; i < ARRAY_SIZE(gpio_display_mux->next); i++) { > + next = gpio_display_mux->next[i]; > + if (next && next->funcs->post_disable) > + next->funcs->post_disable(next); > + } > +} > + > +static const struct drm_bridge_funcs gpio_display_mux_bridge_funcs = { > + .attach = gpio_display_mux_attach, > + .mode_fixup = gpio_display_mux_mode_fixup, > + .disable = gpio_display_mux_disable, > + .post_disable = gpio_display_mux_post_disable, > + .mode_set = gpio_display_mux_mode_set, > + .pre_enable = gpio_display_mux_pre_enable, > + .enable = gpio_display_mux_enable, > +}; > + > +static int gpio_display_mux_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct gpio_display_mux *gpio_display_mux; > + struct device_node *port, *ep, *remote; > + int ret; > + u32 reg; > + > + gpio_display_mux = devm_kzalloc(dev, sizeof(*gpio_display_mux), > + GFP_KERNEL); > + if (!gpio_display_mux) > + return -ENOMEM; > + > + mutex_init(&gpio_display_mux->lock); > + > + platform_set_drvdata(pdev, gpio_display_mux); > + gpio_display_mux->dev = &pdev->dev; > + > + gpio_display_mux->bridge.of_node = dev->of_node; > + > + gpio_display_mux->gpiod_detect = > + devm_gpiod_get(dev, "detect", GPIOD_IN); > + if (IS_ERR(gpio_display_mux->gpiod_detect)) > + return PTR_ERR(gpio_display_mux->gpiod_detect); > + > + gpio_display_mux->detect_irq = > + gpiod_to_irq(gpio_display_mux->gpiod_detect); > + if (gpio_display_mux->detect_irq < 0) { > + dev_err(dev, "Failed to get output irq %d\n", > + gpio_display_mux->detect_irq); > + return -ENODEV; > + } > + > + port = of_graph_get_port_by_id(dev->of_node, 1); > + if (!port) { > + dev_err(dev, "Missing output port node\n"); > + return -EINVAL; > + } > + > + for_each_child_of_node(port, ep) { > + if (!ep->name || (of_node_cmp(ep->name, "endpoint") != 0)) { > + of_node_put(ep); > + continue; > + } > + > + if (of_property_read_u32(ep, "reg", ®) < 0 || > + reg >= ARRAY_SIZE(gpio_display_mux->next)) { > + dev_err(dev, > + "Missing/invalid reg property for endpoint %s\n", > + ep->full_name); > + of_node_put(ep); > + of_node_put(port); > + return -EINVAL; > + } > + > + remote = of_graph_get_remote_port_parent(ep); > + if (!remote) { > + dev_err(dev, > + "Missing connector/bridge node for endpoint %s\n", > + ep->full_name); > + of_node_put(ep); > + of_node_put(port); > + return -EINVAL; > + } > + of_node_put(ep); > + > + if (of_device_is_compatible(remote, "hdmi-connector")) { > + of_node_put(remote); > + continue; > + } > + > + gpio_display_mux->next[reg] = of_drm_find_bridge(remote); > + if (!gpio_display_mux->next[reg]) { > + dev_err(dev, "Waiting for external bridge %s\n", > + remote->name); > + of_node_put(remote); > + of_node_put(port); > + return -EPROBE_DEFER; > + } > + > + of_node_put(remote); > + } > + of_node_put(port); > + > + gpio_display_mux->bridge.funcs = &gpio_display_mux_bridge_funcs; > + ret = drm_bridge_add(&gpio_display_mux->bridge); > + if (ret < 0) { > + dev_err(dev, "Failed to add drm bridge\n"); > + return ret; > + } > + > + ret = devm_request_threaded_irq(dev, gpio_display_mux->detect_irq, > + NULL, > + gpio_display_mux_det_threaded_handler, > + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | > + IRQF_ONESHOT, > + "gpio-display-mux-det", gpio_display_mux); > + if (ret) { > + dev_err(dev, "Failed to request MUX_DET threaded irq\n"); > + goto err_bridge_remove; > + } > + > + gpio_display_mux->active = > + gpiod_get_value(gpio_display_mux->gpiod_detect); > + > + return 0; > + > +err_bridge_remove: > + drm_bridge_remove(&gpio_display_mux->bridge); > + > + return ret; > +} > + > +static int gpio_display_mux_remove(struct platform_device *pdev) > +{ > + struct gpio_display_mux *gpio_display_mux = platform_get_drvdata(pdev); > + > + drm_bridge_remove(&gpio_display_mux->bridge); > + > + return 0; > +} > + > +static const struct of_device_id gpio_display_mux_match[] = { > + { .compatible = "gpio-display-mux", }, > + {}, > +}; > + > +struct platform_driver gpio_display_mux_driver = { > + .probe = gpio_display_mux_probe, > + .remove = gpio_display_mux_remove, > + .driver = { > + .name = "gpio-display-mux", > + .of_match_table = gpio_display_mux_match, > + }, > +}; > + > +module_platform_driver(gpio_display_mux_driver); > + > +MODULE_DESCRIPTION("GPIO-controlled display mux"); > +MODULE_AUTHOR("Nicolas Boichat "); > +MODULE_LICENSE("GPL v2"); > -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project