From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Shevchenko, Andriy" Subject: Re: [PATCH v2 1/2] dmaengine: add Qualcomm BAM dma driver Date: Mon, 13 Jan 2014 10:31:01 +0000 Message-ID: <1389609060.1871.312.camel@smile> References: <1389380874-22753-1-git-send-email-agross@codeaurora.org> <1389380874-22753-2-git-send-email-agross@codeaurora.org> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mga14.intel.com ([143.182.124.37]:24757 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751327AbaAMKbz (ORCPT ); Mon, 13 Jan 2014 05:31:55 -0500 In-Reply-To: <1389380874-22753-2-git-send-email-agross@codeaurora.org> Content-Language: en-US Content-ID: Sender: linux-arm-msm-owner@vger.kernel.org List-Id: linux-arm-msm@vger.kernel.org To: Andy Gross Cc: "Koul, Vinod" , "Williams, Dan J" , "dmaengine@vger.kernel.org" , "linux-arm-kernel@lists.infradead.org" , "linux-arm-msm@vger.kernel.org" , "devicetree@vger.kernel.org" T24gRnJpLCAyMDE0LTAxLTEwIGF0IDEzOjA3IC0wNjAwLCBBbmR5IEdyb3NzIHdyb3RlOg0KPiBB ZGQgdGhlIERNQSBlbmdpbmUgZHJpdmVyIGZvciB0aGUgUUNPTSBCdXMgQWNjZXNzIE1hbmFnZXIg KEJBTSkgRE1BIGNvbnRyb2xsZXINCj4gZm91bmQgaW4gdGhlIE1TTSA4eDc0IHBsYXRmb3Jtcy4N Cj4gDQo+IEVhY2ggQkFNIERNQSBkZXZpY2UgaXMgYXNzb2NpYXRlZCB3aXRoIGEgc3BlY2lmaWMg b24tY2hpcCBwZXJpcGhlcmFsLiAgRWFjaA0KPiBjaGFubmVsIHByb3ZpZGVzIGEgdW5pLWRpcmVj dGlvbmFsIGRhdGEgdHJhbnNmZXIgZW5naW5lIHRoYXQgaXMgY2FwYWJsZSBvZg0KPiB0cmFuc2Zl cnJpbmcgZGF0YSBiZXR3ZWVuIHRoZSBwZXJpcGhlcmFsIGFuZCBzeXN0ZW0gbWVtb3J5IChTeXN0 ZW0gbW9kZSksIG9yDQo+IGJldHdlZW4gdHdvIHBlcmlwaGVyYWxzIChCQU0yQkFNKS4NCj4gDQo+ IFRoZSBpbml0aWFsIHJlbGVhc2Ugb2YgdGhpcyBkcml2ZXIgb25seSBzdXBwb3J0cyBzbGF2ZSB0 cmFuc2ZlcnMgYmV0d2Vlbg0KPiBwZXJpcGhlcmFscyBhbmQgc3lzdGVtIG1lbW9yeS4NCj4gDQo+ IFNpZ25lZC1vZmYtYnk6IEFuZHkgR3Jvc3MgPGFncm9zc0Bjb2RlYXVyb3JhLm9yZz4NCj4gLS0t DQo+ICBkcml2ZXJzL2RtYS9LY29uZmlnICAgICAgICB8ICAgOSArDQo+ICBkcml2ZXJzL2RtYS9N YWtlZmlsZSAgICAgICB8ICAgMSArDQo+ICBkcml2ZXJzL2RtYS9xY29tX2JhbV9kbWEuYyB8IDg0 MyArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysNCj4gIGRyaXZl cnMvZG1hL3Fjb21fYmFtX2RtYS5oIHwgMjY4ICsrKysrKysrKysrKysrDQo+ICA0IGZpbGVzIGNo YW5nZWQsIDExMjEgaW5zZXJ0aW9ucygrKQ0KPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMv ZG1hL3Fjb21fYmFtX2RtYS5jDQo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9kbWEvcWNv bV9iYW1fZG1hLmgNCj4gDQo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2RtYS9LY29uZmlnIGIvZHJp dmVycy9kbWEvS2NvbmZpZw0KPiBpbmRleCBjODIzZGFhLi5lNThlNmQyIDEwMDY0NA0KPiAtLS0g YS9kcml2ZXJzL2RtYS9LY29uZmlnDQo+ICsrKyBiL2RyaXZlcnMvZG1hL0tjb25maWcNCj4gQEAg LTM4NCw0ICszODQsMTMgQEAgY29uZmlnIERNQVRFU1QNCj4gIGNvbmZpZyBETUFfRU5HSU5FX1JB SUQNCj4gIAlib29sDQo+ICANCj4gK2NvbmZpZyBRQ09NX0JBTV9ETUENCj4gKwl0cmlzdGF0ZSAi UUNPTSBCQU0gRE1BIHN1cHBvcnQiDQo+ICsJZGVwZW5kcyBvbiBBUkNIX01TTSB8fCBDT01QSUxF X1RFU1QNCj4gKwlzZWxlY3QgRE1BX0VOR0lORQ0KPiArCXNlbGVjdCBETUFfVklSVFVBTF9DSEFO TkVMUw0KPiArCS0tLWhlbHAtLS0NCj4gKwkgIEVuYWJsZSBzdXBwb3J0IGZvciB0aGUgUUNPTSBC QU0gRE1BIGNvbnRyb2xsZXIuICBUaGlzIGNvbnRyb2xsZXINCj4gKwkgIHByb3ZpZGVzIERNQSBj YXBhYmlsaXRpZXMgZm9yIGEgdmFyaWV0eSBvZiBvbi1jaGlwIGRldmljZXMuDQo+ICsNCj4gIGVu ZGlmDQo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2RtYS9NYWtlZmlsZSBiL2RyaXZlcnMvZG1hL01h a2VmaWxlDQo+IGluZGV4IDBjZTJkYTkuLjdlZjk1MGEgMTAwNjQ0DQo+IC0tLSBhL2RyaXZlcnMv ZG1hL01ha2VmaWxlDQo+ICsrKyBiL2RyaXZlcnMvZG1hL01ha2VmaWxlDQo+IEBAIC00MiwzICs0 Miw0IEBAIG9iai0kKENPTkZJR19NTVBfUERNQSkgKz0gbW1wX3BkbWEubw0KPiAgb2JqLSQoQ09O RklHX0RNQV9KWjQ3NDApICs9IGRtYS1qejQ3NDAubw0KPiAgb2JqLSQoQ09ORklHX1RJX0NQUEk0 MSkgKz0gY3BwaTQxLm8NCj4gIG9iai0kKENPTkZJR19LM19ETUEpICs9IGszZG1hLm8NCj4gK29i ai0kKENPTkZJR19RQ09NX0JBTV9ETUEpICs9IHFjb21fYmFtX2RtYS5vDQo+IGRpZmYgLS1naXQg YS9kcml2ZXJzL2RtYS9xY29tX2JhbV9kbWEuYyBiL2RyaXZlcnMvZG1hL3Fjb21fYmFtX2RtYS5j DQo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+IGluZGV4IDAwMDAwMDAuLjdhODRiMDINCj4gLS0t IC9kZXYvbnVsbA0KPiArKysgYi9kcml2ZXJzL2RtYS9xY29tX2JhbV9kbWEuYw0KPiBAQCAtMCww ICsxLDg0MyBAQA0KPiArLyoNCj4gKyAqIFFDT00gQkFNIERNQSBlbmdpbmUgZHJpdmVyDQo+ICsg Kg0KPiArICogQ29weXJpZ2h0IChjKSAyMDEzLCBUaGUgTGludXggRm91bmRhdGlvbi4gQWxsIHJp Z2h0cyByZXNlcnZlZC4NCj4gKyAqDQo+ICsgKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2Fy ZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQ0KPiArICogaXQgdW5kZXIg dGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgYW5k DQo+ICsgKiBvbmx5IHZlcnNpb24gMiBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUg Rm91bmRhdGlvbi4NCj4gKyAqDQo+ICsgKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4g dGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwNCj4gKyAqIGJ1dCBXSVRIT1VUIEFOWSBX QVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mDQo+ICsgKiBNRVJD SEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhl DQo+ICsgKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLg0KPiAr ICoNCj4gKyAqDQo+ICsgKiBRQ09NIEJBTSBETUEgYmxvY2tzIGFyZSBkaXN0cmlidXRlZCBhbW9u Z3N0IGEgbnVtYmVyIG9mIHRoZSBvbi1jaGlwDQo+ICsgKiBwZXJpcGhlcmFscyBvbiB0aGUgTVNN IDh4NzQuICBUaGUgY29uZmlndXJhdGlvbiBvZiB0aGUgY2hhbm5lbHMgYXJlIGRlcGVuZGVudA0K PiArICogb24gdGhlIHdheSB0aGV5IGFyZSBoYXJkIHdpcmVkIHRvIHRoYXQgc3BlY2lmaWMgcGVy aXBoZXJhbC4gIFRoZSBwZXJpcGhlcmFsDQo+ICsgKiBkZXZpY2UgdHJlZSBlbnRyaWVzIHNwZWNp ZnkgdGhlIGNvbmZpZ3VyYXRpb24gb2YgZWFjaCBjaGFubmVsLg0KPiArICoNCj4gKyAqIFRoZSBE TUEgY29udHJvbGxlciByZXF1aXJlcyB0aGUgdXNlIG9mIGV4dGVybmFsIG1lbW9yeSBmb3Igc3Rv cmFnZSBvZiB0aGUNCj4gKyAqIGhhcmR3YXJlIGRlc2NyaXB0b3JzIGZvciBlYWNoIGNoYW5uZWwu ICBUaGUgZGVzY3JpcHRvciBGSUZPIGlzIGFjY2Vzc2VkIGFzIGENCj4gKyAqIGNpcmN1bGFyIGJ1 ZmZlciBhbmQgb3BlcmF0aW9ucyBhcmUgbWFuYWdlZCBhY2NvcmRpbmcgdG8gdGhlIG9mZnNldCB3 aXRoaW4gdGhlDQo+ICsgKiBGSUZPLiAgQWZ0ZXIgcGlwZS9jaGFubmVsIHJlc2V0LCBhbGwgb2Yg dGhlIHBpcGUgcmVnaXN0ZXJzIGFuZCBpbnRlcm5hbCBzdGF0ZQ0KPiArICogYXJlIGJhY2sgdG8g ZGVmYXVsdHMuDQo+ICsgKg0KPiArICogRHVyaW5nIERNQSBvcGVyYXRpb25zLCB3ZSB3cml0ZSBk ZXNjcmlwdG9ycyB0byB0aGUgRklGTywgYmVpbmcgY2FyZWZ1bCB0bw0KPiArICogaGFuZGxlIHdy YXBwaW5nIGFuZCB0aGVuIHdyaXRlIHRoZSBsYXN0IEZJRk8gb2Zmc2V0IHRvIHRoYXQgY2hhbm5l bCdzDQo+ICsgKiBQX0VWTlRfUkVHIHJlZ2lzdGVyIHRvIGtpY2sgb2ZmIHRoZSB0cmFuc2FjdGlv bi4gIFRoZSBQX1NXX09GU1RTIHJlZ2lzdGVyDQo+ICsgKiBpbmRpY2F0ZXMgdGhlIGN1cnJlbnQg RklGTyBvZmZzZXQgdGhhdCBpcyBiZWluZyBwcm9jZXNzZWQsIHNvIHRoZXJlIGlzIHNvbWUNCj4g KyAqIGluZGljYXRpb24gb2Ygd2hlcmUgdGhlIGhhcmR3YXJlIGlzIGN1cnJlbnRseSB3b3JraW5n Lg0KPiArICovDQo+ICsNCj4gKyNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4NCj4gKyNpbmNsdWRl IDxsaW51eC9pby5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4NCj4gKyNpbmNsdWRlIDxs aW51eC9zbGFiLmg+DQo+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+DQo+ICsjaW5jbHVkZSA8 bGludXgvaW50ZXJydXB0Lmg+DQo+ICsjaW5jbHVkZSA8bGludXgvZG1hLW1hcHBpbmcuaD4NCj4g KyNpbmNsdWRlIDxsaW51eC9zY2F0dGVybGlzdC5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2Rldmlj ZS5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPg0KPiArI2luY2x1ZGUg PGxpbnV4L29mLmg+DQo+ICsjaW5jbHVkZSA8bGludXgvb2ZfYWRkcmVzcy5oPg0KPiArI2luY2x1 ZGUgPGxpbnV4L29mX2lycS5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L29mX2RtYS5oPg0KPiArI2lu Y2x1ZGUgPGxpbnV4L2Nsay5oPg0KPiArDQo+ICsjaW5jbHVkZSAiZG1hZW5naW5lLmgiDQo+ICsj aW5jbHVkZSAicWNvbV9iYW1fZG1hLmgiDQo+ICsNCj4gKw0KPiArLyoqDQo+ICsgKiBiYW1fcmVz ZXRfY2hhbm5lbCAtIFJlc2V0IGluZGl2aWR1YWwgQkFNIERNQSBjaGFubmVsDQo+ICsgKiBAYmRl djogYmFtIGRldmljZQ0KPiArICogQGNoYW5uZWw6IGNoYW5uZWwgaWQNCj4gKyAqLw0KPiArc3Rh dGljIHZvaWQgYmFtX3Jlc2V0X2NoYW5uZWwoc3RydWN0IGJhbV9kZXZpY2UgKmJkZXYsIHUzMiBj aGFubmVsKQ0KPiArew0KPiArCS8qIHJlc2V0IGNoYW5uZWwgKi8NCj4gKwl3cml0ZWxfcmVsYXhl ZCgxLCBiZGV2LT5yZWdzICsgQkFNX1BfUlNUKGNoYW5uZWwpKTsNCj4gKwl3cml0ZWxfcmVsYXhl ZCgwLCBiZGV2LT5yZWdzICsgQkFNX1BfUlNUKGNoYW5uZWwpKTsNCj4gK30NCj4gKw0KPiArLyoq DQo+ICsgKiBiYW1fYWxsb2NfY2hhbiAtIEFsbG9jYXRlIGNoYW5uZWwgcmVzb3VyY2VzIGZvciBE TUEgY2hhbm5lbC4NCj4gKyAqIEBjaGFuOiBzcGVjaWZpZWQgY2hhbm5lbA0KPiArICoNCj4gKyAq IFRoaXMgZnVuY3Rpb24gYWxsb2NhdGVzIHRoZSBGSUZPIGRlc2NyaXB0b3IgbWVtb3J5IGFuZCBy ZXNldHMgdGhlIGNoYW5uZWwNCj4gKyAqLw0KPiArc3RhdGljIGludCBiYW1fYWxsb2NfY2hhbihz dHJ1Y3QgZG1hX2NoYW4gKmNoYW4pDQo+ICt7DQo+ICsJc3RydWN0IGJhbV9jaGFuICpiY2hhbiA9 IHRvX2JhbV9jaGFuKGNoYW4pOw0KPiArCXN0cnVjdCBiYW1fZGV2aWNlICpiZGV2ID0gYmNoYW4t PmJkZXY7DQo+ICsJdTMyIHZhbDsNCj4gKw0KPiArCS8qIGFsbG9jYXRlIEZJRk8gZGVzY3JpcHRv ciBzcGFjZSwgYnV0IG9ubHkgaWYgbmVjZXNzYXJ5ICovDQo+ICsJaWYgKCFiY2hhbi0+Zmlmb192 aXJ0KSB7DQo+ICsJCWJjaGFuLT5maWZvX3ZpcnQgPSBkbWFfYWxsb2NfY29oZXJlbnQoYmRldi0+ ZGV2LA0KPiArCQkJCQlCQU1fREVTQ19GSUZPX1NJWkUsICZiY2hhbi0+Zmlmb19waHlzLA0KPiAr CQkJCQlHRlBfS0VSTkVMKTsNCj4gKw0KPiArCQlpZiAoIWJjaGFuLT5maWZvX3ZpcnQpIHsNCj4g KwkJCWRldl9lcnIoYmRldi0+ZGV2LCAiRmFpbGVkIHRvIGFsbG9jYXRlIGRlc2MgZmlmb1xuIik7 DQo+ICsJCQlyZXR1cm4gLUVOT01FTTsNCj4gKwkJfQ0KPiArCX0NCj4gKw0KPiArCS8qIEdvIGFo ZWFkIGFuZCBpbml0aWFsaXplIHRoZSBwaXBlL2NoYW5uZWwgaGFyZHdhcmUgaGVyZQ0KPiArCSAg IC0gUmVzZXQgdGhlIGNoYW5uZWwgdG8gY2xlYXIgaW50ZXJuYWwgc3RhdGUgb2YgdGhlIEZJRk8N Cj4gKwkgICAtIFByb2dyYW0gaW4gdGhlIEZJRk8gYWRkcmVzcw0KPiArCSAgIC0gQ29uZmlndXJl IHRoZSBpcnEgYmFzZWQgb24gdGhlIEVFIHBhc3NlZCBpbiBmcm9tIHRoZSBEVCBlbnRyeQ0KPiAr CSAgIC0gU2V0IG1vZGUsIGRpcmVjdGlvbiBhbmQgZW5hYmxlIGNoYW5uZWwNCj4gKw0KPiArCSAg IFdlIGRvIHRoaXMgaGVyZSBiZWNhdXNlIHRoZSBjaGFubmVsIGNhbiBvbmx5IGJlIGVuYWJsZWQg b25jZSBhbmQNCj4gKwkgICBjYW4gb25seSBiZSBkaXNhYmxlZCB2aWEgYSByZXNldC4gIElmIGRv bmUgaGVyZSwgd2UgZG9uJ3QgaGF2ZSB0bw0KPiArCSAgIG1hbmFnZSBhZGRpdGlvbmFsIHN0YXRl IHRvIGZpZ3VyZSBvdXQgd2hlbiB0byBkbyB0aGlzDQo+ICsJKi8NCj4gKw0KPiArCWJhbV9yZXNl dF9jaGFubmVsKGJkZXYsIGJjaGFuLT5pZCk7DQo+ICsNCj4gKwkvKiB3cml0ZSBvdXQgOCBieXRl IGFsaWduZWQgYWRkcmVzcy4gIFdlIGhhdmUgZW5vdWdoIHNwYWNlIGZvciB0aGlzDQo+ICsJICAg YmVjYXVzZSB3ZSBhbGxvY2F0ZWQgMSBtb3JlIGRlc2NyaXB0b3IgKDggYnl0ZXMpIHRoYW4gd2Ug Y2FuIHVzZSAqLw0KPiArCXdyaXRlbF9yZWxheGVkKEFMSUdOKGJjaGFuLT5maWZvX3BoeXMsIHNp emVvZihzdHJ1Y3QgYmFtX2Rlc2NfaHcpKSwNCj4gKwkJCWJkZXYtPnJlZ3MgKyBCQU1fUF9ERVND X0ZJRk9fQUREUihiY2hhbi0+aWQpKTsNCj4gKwl3cml0ZWxfcmVsYXhlZChCQU1fREVTQ19GSUZP X1NJWkUsIGJkZXYtPnJlZ3MgKw0KPiArCQkJQkFNX1BfRklGT19TSVpFUyhiY2hhbi0+aWQpKTsN Cj4gKw0KPiArCS8qIHVubWFzayBhbmQgZW5hYmxlIGludGVycnVwdHMgZm9yIGRlZmluZWQgRUUs IGJhbSBhbmQgZXJyb3IgaXJxcyAqLw0KPiArCXdyaXRlbF9yZWxheGVkKEJBTV9JUlFfTVNLLCBi ZGV2LT5yZWdzICsgQkFNX0lSUV9TUkNTX0VFKGJjaGFuLT5lZSkpOw0KPiArDQo+ICsJLyogZW5h YmxlIHRoZSBwZXIgcGlwZSBpbnRlcnJ1cHRzLCBlbmFibGUgRU9ULCBFUlIsIGFuZCBJTlQgaXJx cyAqLw0KPiArCXdyaXRlbF9yZWxheGVkKFBfREVGQVVMVF9JUlFTX0VOLCBiZGV2LT5yZWdzICsg QkFNX1BfSVJRX0VOKGJjaGFuLT5pZCkpOw0KPiArDQo+ICsJLyogdW5tYXNrIHRoZSBzcGVjaWZp YyBwaXBlIGFuZCBFRSBjb21ibyAqLw0KPiArCXZhbCA9IHJlYWRsX3JlbGF4ZWQoYmRldi0+cmVn cyArIEJBTV9JUlFfU1JDU19NU0tfRUUoYmNoYW4tPmVlKSk7DQo+ICsJdmFsIHw9IEJJVChiY2hh bi0+aWQpOw0KPiArCXdyaXRlbF9yZWxheGVkKHZhbCwgYmRldi0+cmVncyArIEJBTV9JUlFfU1JD U19NU0tfRUUoYmNoYW4tPmVlKSk7DQo+ICsNCj4gKwkvKiBzZXQgZml4ZWQgZGlyZWN0aW9uIGFu ZCBtb2RlLCB0aGVuIGVuYWJsZSBjaGFubmVsICovDQo+ICsJdmFsID0gUF9FTiB8IFBfU1lTX01P REU7DQo+ICsJaWYgKGJjaGFuLT5zbGF2ZS5kaXJlY3Rpb24gPT0gRE1BX0RFVl9UT19NRU0pDQo+ ICsJCXZhbCB8PSBQX0RJUkVDVElPTjsNCj4gKw0KPiArCS8qIG1ha2Ugc3VyZSB0aGUgb3RoZXIg c3RvcmVzIG9jY3VyIGJlZm9yZSBlbmFibGluZyBjaGFubmVsICovDQo+ICsJd21iKCk7DQo+ICsJ d3JpdGVsX3JlbGF4ZWQodmFsLCBiZGV2LT5yZWdzICsgQkFNX1BfQ1RSTChiY2hhbi0+aWQpKTsN Cj4gKw0KPiArCS8qIGRvIGJvb2trZWVwaW5nIGZvciB0cmFja2luZyB1c2VkIEVFcywgdXNlZCBk dXJpbmcgSVJRIGhhbmRsaW5nICovDQo+ICsJc2V0X2JpdChiY2hhbi0+ZWUsICZiZGV2LT5lbmFi bGVkX2Vlcyk7DQo+ICsNCj4gKwliY2hhbi0+aGVhZCA9IDA7DQo+ICsJYmNoYW4tPnRhaWwgPSAw Ow0KPiArDQo+ICsJcmV0dXJuIEJBTV9ERVNDX0ZJRk9fU0laRTsNCj4gK30NCj4gKw0KPiArLyoq DQo+ICsgKiBiYW1fZnJlZV9jaGFuIC0gRnJlZXMgZG1hIHJlc291cmNlcyBhc3NvY2lhdGVkIHdp dGggc3BlY2lmaWMgY2hhbm5lbA0KPiArICogQGNoYW46IHNwZWNpZmllZCBjaGFubmVsDQo+ICsg Kg0KPiArICogRnJlZSB0aGUgYWxsb2NhdGVkIGZpZm8gZGVzY3JpcHRvciBtZW1vcnkgYW5kIGNo YW5uZWwgcmVzb3VyY2VzDQo+ICsgKg0KPiArICovDQo+ICtzdGF0aWMgdm9pZCBiYW1fZnJlZV9j aGFuKHN0cnVjdCBkbWFfY2hhbiAqY2hhbikNCj4gK3sNCj4gKwlzdHJ1Y3QgYmFtX2NoYW4gKmJj aGFuID0gdG9fYmFtX2NoYW4oY2hhbik7DQo+ICsJc3RydWN0IGJhbV9kZXZpY2UgKmJkZXYgPSBi Y2hhbi0+YmRldjsNCj4gKwl1MzIgdmFsOw0KPiArDQo+ICsJdmNoYW5fZnJlZV9jaGFuX3Jlc291 cmNlcyh0b192aXJ0X2NoYW4oY2hhbikpOw0KPiArDQo+ICsJaWYgKGJjaGFuLT5jdXJyX3R4ZCkg ew0KPiArCQlkZXZfZXJyKGJjaGFuLT5iZGV2LT5kZXYsICJDYW5ub3QgZnJlZSBidXN5IGNoYW5u ZWxcbiIpOw0KPiArCQlyZXR1cm47DQo+ICsJfQ0KPiArDQo+ICsJYmFtX3Jlc2V0X2NoYW5uZWwo YmRldiwgYmNoYW4tPmlkKTsNCj4gKw0KPiArCWRtYV9mcmVlX2NvaGVyZW50KGJkZXYtPmRldiwg QkFNX0RFU0NfRklGT19TSVpFLCBiY2hhbi0+Zmlmb192aXJ0LA0KPiArCQkJCWJjaGFuLT5maWZv X3BoeXMpOw0KPiArCWJjaGFuLT5maWZvX3ZpcnQgPSBOVUxMOw0KPiArDQo+ICsJLyogbWFzayBp cnEgZm9yIHBpcGUvY2hhbm5lbCAqLw0KPiArCXZhbCA9IHJlYWRsX3JlbGF4ZWQoYmRldi0+cmVn cyArIEJBTV9JUlFfU1JDU19NU0tfRUUoYmNoYW4tPmVlKSk7DQo+ICsJdmFsICY9IH5CSVQoYmNo YW4tPmlkKTsNCj4gKwl3cml0ZWxfcmVsYXhlZCh2YWwsIGJkZXYtPnJlZ3MgKyBCQU1fSVJRX1NS Q1NfTVNLX0VFKGJjaGFuLT5lZSkpOw0KPiArDQo+ICsJLyogZGlzYWJsZSBpcnEgKi8NCj4gKwl3 cml0ZWxfcmVsYXhlZCgwLCBiZGV2LT5yZWdzICsgQkFNX1BfSVJRX0VOKGJjaGFuLT5pZCkpOw0K PiArDQo+ICsJY2xlYXJfYml0KGJjaGFuLT5lZSwgJmJkZXYtPmVuYWJsZWRfZWVzKTsNCj4gK30N Cj4gKw0KPiArLyoqDQo+ICsgKiBiYW1fc2xhdmVfY29uZmlnIC0gc2V0IHNsYXZlIGNvbmZpZ3Vy YXRpb24gZm9yIGNoYW5uZWwNCj4gKyAqIEBjaGFuOiBkbWEgY2hhbm5lbA0KPiArICogQGNmZzog c2xhdmUgY29uZmlndXJhdGlvbg0KPiArICoNCj4gKyAqIFNldHMgc2xhdmUgY29uZmlndXJhdGlv biBmb3IgY2hhbm5lbA0KPiArICogT25seSBhbGxvdyBzZXR0aW5nIGRpcmVjdGlvbiBvbmNlLiAg QkFNIGNoYW5uZWxzIGFyZSB1bmlkaXJlY3Rpb25hbA0KPiArICogYW5kIHRoZSBkaXJlY3Rpb24g aXMgc2V0IGluIGhhcmR3YXJlLg0KPiArICoNCj4gKyAqLw0KPiArc3RhdGljIHZvaWQgYmFtX3Ns YXZlX2NvbmZpZyhzdHJ1Y3QgYmFtX2NoYW4gKmJjaGFuLA0KPiArCQlzdHJ1Y3QgZG1hX3NsYXZl X2NvbmZpZyAqY2ZnKQ0KPiArew0KPiArCXN0cnVjdCBiYW1fZGV2aWNlICpiZGV2ID0gYmNoYW4t PmJkZXY7DQo+ICsJdTMyIG1heGJ1cnN0Ow0KPiArDQo+ICsJaWYgKGJjaGFuLT5zbGF2ZS5kaXJl Y3Rpb24gPT0gRE1BX0RFVl9UT19NRU0pDQo+ICsJCW1heGJ1cnN0ID0gYmNoYW4tPnNsYXZlLnNy Y19tYXhidXJzdCA9IGNmZy0+c3JjX21heGJ1cnN0Ow0KPiArCWVsc2UNCj4gKwkJbWF4YnVyc3Qg PSBiY2hhbi0+c2xhdmUuZHN0X21heGJ1cnN0ID0gY2ZnLT5kc3RfbWF4YnVyc3Q7DQo+ICsNCj4g KwkvKiBzZXQgZGVzYyB0aHJlc2hvbGQgKi8NCj4gKwl3cml0ZWxfcmVsYXhlZChtYXhidXJzdCwg YmRldi0+cmVncyArIEJBTV9ERVNDX0NOVF9UUlNITEQpOw0KPiArfQ0KPiArDQo+ICsvKioNCj4g KyAqIGJhbV9wcmVwX3NsYXZlX3NnIC0gUHJlcCBzbGF2ZSBzZyB0cmFuc2FjdGlvbg0KPiArICoN Cj4gKyAqIEBjaGFuOiBkbWEgY2hhbm5lbA0KPiArICogQHNnbDogc2NhdHRlciBnYXRoZXIgbGlz dA0KPiArICogQHNnX2xlbjogbGVuZ3RoIG9mIHNnDQo+ICsgKiBAZGlyZWN0aW9uOiBETUEgdHJh bnNmZXIgZGlyZWN0aW9uDQo+ICsgKiBAZmxhZ3M6IERNQSBmbGFncw0KPiArICogQGNvbnRleHQ6 IHRyYW5zZmVyIGNvbnRleHQgKHVudXNlZCkNCj4gKyAqLw0KPiArc3RhdGljIHN0cnVjdCBkbWFf YXN5bmNfdHhfZGVzY3JpcHRvciAqYmFtX3ByZXBfc2xhdmVfc2coc3RydWN0IGRtYV9jaGFuICpj aGFuLA0KPiArCXN0cnVjdCBzY2F0dGVybGlzdCAqc2dsLCB1bnNpZ25lZCBpbnQgc2dfbGVuLA0K PiArCWVudW0gZG1hX3RyYW5zZmVyX2RpcmVjdGlvbiBkaXJlY3Rpb24sIHVuc2lnbmVkIGxvbmcg ZmxhZ3MsDQo+ICsJdm9pZCAqY29udGV4dCkNCj4gK3sNCj4gKwlzdHJ1Y3QgYmFtX2NoYW4gKmJj aGFuID0gdG9fYmFtX2NoYW4oY2hhbik7DQo+ICsJc3RydWN0IGJhbV9kZXZpY2UgKmJkZXYgPSBi Y2hhbi0+YmRldjsNCj4gKwlzdHJ1Y3QgYmFtX2FzeW5jX2Rlc2MgKmFzeW5jX2Rlc2M7DQo+ICsJ c3RydWN0IHNjYXR0ZXJsaXN0ICpzZzsNCj4gKwl1MzIgaTsNCj4gKwlzdHJ1Y3QgYmFtX2Rlc2Nf aHcgKmRlc2M7DQo+ICsNCj4gKw0KPiArCWlmICghaXNfc2xhdmVfZGlyZWN0aW9uKGRpcmVjdGlv bikpIHsNCj4gKwkJZGV2X2VycihiZGV2LT5kZXYsICJpbnZhbGlkIGRtYSBkaXJlY3Rpb25cbiIp Ow0KPiArCQlyZXR1cm4gTlVMTDsNCj4gKwl9DQo+ICsNCj4gKwkvKiBkaXJlY3Rpb24gaGFzIHRv IG1hdGNoIHBpcGUgY29uZmlndXJhdGlvbiBmcm9tIHRoZSBzbGF2ZSBjb25maWcgKi8NCj4gKwlp ZiAoZGlyZWN0aW9uICE9IGJjaGFuLT5zbGF2ZS5kaXJlY3Rpb24pIHsNCj4gKwkJZGV2X2Vycihi ZGV2LT5kZXYsDQo+ICsJCQkJImRpcmVjdGlvbiBkb2VzIG5vdCBtYXRjaCBjb25maWd1cmF0aW9u XG4iKTsNCj4gKwkJcmV0dXJuIE5VTEw7DQo+ICsJfQ0KPiArDQo+ICsJLyogYWxsb2NhdGUgZW5v dWdoIHJvb20gdG8gYWNjb21vZGF0ZSB0aGUgbnVtYmVyIG9mIGVudHJpZXMgKi8NCj4gKwlhc3lu Y19kZXNjID0ga3phbGxvYyhzaXplb2YoKmFzeW5jX2Rlc2MpICsNCj4gKwkJCShzZ19sZW4gKiBz aXplb2Yoc3RydWN0IGJhbV9kZXNjX2h3KSksIEdGUF9OT1dBSVQpOw0KPiArDQo+ICsJaWYgKCFh c3luY19kZXNjKSB7DQo+ICsJCWRldl9lcnIoYmRldi0+ZGV2LCAiZmFpbGVkIHRvIGFsbG9jYXRl IGFzeW5jIGRlc2NyaXB0b3JcbiIpOw0KPiArCQlnb3RvIGVycl9vdXQ7DQo+ICsJfQ0KPiArDQo+ ICsJYXN5bmNfZGVzYy0+bnVtX2Rlc2MgPSBzZ19sZW47DQo+ICsJYXN5bmNfZGVzYy0+Y3Vycl9k ZXNjID0gYXN5bmNfZGVzYy0+ZGVzYzsNCj4gKwlhc3luY19kZXNjLT5kaXIgPSAoZGlyZWN0aW9u ID09IERNQV9ERVZfVE9fTUVNKSA/IEJBTV9QSVBFX1BST0RVQ0VSIDoNCj4gKwkJCQlCQU1fUElQ RV9DT05TVU1FUjsNCj4gKw0KPiArCS8qIGZpbGwgaW4gZGVzY3JpcHRvcnMsIGFsaWduIGh3IGRl c2NyaXB0b3IgdG8gOCBieXRlcyAqLw0KPiArCWRlc2MgPSBhc3luY19kZXNjLT5kZXNjOw0KPiAr CWZvcl9lYWNoX3NnKHNnbCwgc2csIHNnX2xlbiwgaSkgew0KPiArCQlpZiAoc2dfZG1hX2xlbihz ZykgPiBCQU1fTUFYX0RBVEFfU0laRSkgew0KPiArCQkJZGV2X2VycihiZGV2LT5kZXYsICJzZWdt ZW50IGV4Y2VlZHMgbWF4IHNpemVcbiIpOw0KPiArCQkJZ290byBlcnJfb3V0Ow0KPiArCQl9DQo+ ICsNCj4gKwkJZGVzYy0+YWRkciA9IHNnX2RtYV9hZGRyZXNzKHNnKTsNCj4gKwkJZGVzYy0+c2l6 ZSA9IHNnX2RtYV9sZW4oc2cpOw0KPiArCQlhc3luY19kZXNjLT5sZW5ndGggKz0gc2dfZG1hX2xl bihzZyk7DQo+ICsJCWRlc2MrKzsNCj4gKwl9DQo+ICsNCj4gKwlyZXR1cm4gdmNoYW5fdHhfcHJl cCgmYmNoYW4tPnZjLCAmYXN5bmNfZGVzYy0+dmQsIGZsYWdzKTsNCj4gKw0KPiArZXJyX291dDoN Cj4gKwlrZnJlZShhc3luY19kZXNjKTsNCj4gKwlyZXR1cm4gTlVMTDsNCj4gK30NCj4gKw0KPiAr LyoqDQo+ICsgKiBiYW1fZG1hX3Rlcm1pbmF0ZV9hbGwgLSB0ZXJtaW5hdGUgYWxsIHRyYW5zYWN0 aW9ucw0KPiArICogQGNoYW46IGRtYSBjaGFubmVsDQo+ICsgKg0KPiArICogSWRsZXMgY2hhbm5l bCBhbmQgZGVxdWV1ZXMgYW5kIGZyZWVzIGFsbCB0cmFuc2FjdGlvbnMNCj4gKyAqIE5vIGNhbGxi YWNrcyBhcmUgZG9uZQ0KPiArICoNCj4gKyovDQo+ICtzdGF0aWMgdm9pZCBiYW1fZG1hX3Rlcm1p bmF0ZV9hbGwoc3RydWN0IGRtYV9jaGFuICpjaGFuKQ0KPiArew0KPiArCXN0cnVjdCBiYW1fY2hh biAqYmNoYW4gPSB0b19iYW1fY2hhbihjaGFuKTsNCj4gKwlzdHJ1Y3QgYmFtX2RldmljZSAqYmRl diA9IGJjaGFuLT5iZGV2Ow0KPiArDQo+ICsJYmFtX3Jlc2V0X2NoYW5uZWwoYmRldiwgYmNoYW4t PmlkKTsNCj4gKw0KPiArCXZjaGFuX2ZyZWVfY2hhbl9yZXNvdXJjZXMoJmJjaGFuLT52Yyk7DQo+ ICt9DQo+ICsNCj4gKy8qKg0KPiArICogYmFtX2NvbnRyb2wgLSBETUEgZGV2aWNlIGNvbnRyb2wN Cj4gKyAqIEBjaGFuOiBkbWEgY2hhbm5lbA0KPiArICogQGNtZDogY29udHJvbCBjbWQNCj4gKyAq IEBhcmc6IGNtZCBhcmd1bWVudA0KPiArICoNCj4gKyAqIFBlcmZvcm0gRE1BIGNvbnRyb2wgY29t bWFuZA0KPiArICoNCj4gKyovDQo+ICtzdGF0aWMgaW50IGJhbV9jb250cm9sKHN0cnVjdCBkbWFf Y2hhbiAqY2hhbiwgZW51bSBkbWFfY3RybF9jbWQgY21kLA0KPiArCXVuc2lnbmVkIGxvbmcgYXJn KQ0KPiArew0KPiArCXN0cnVjdCBiYW1fY2hhbiAqYmNoYW4gPSB0b19iYW1fY2hhbihjaGFuKTsN Cj4gKwlzdHJ1Y3QgYmFtX2RldmljZSAqYmRldiA9IGJjaGFuLT5iZGV2Ow0KPiArCWludCByZXQg PSAwOw0KPiArCXVuc2lnbmVkIGxvbmcgZmxhZzsNCj4gKw0KPiArCXN3aXRjaCAoY21kKSB7DQo+ ICsJY2FzZSBETUFfUEFVU0U6DQo+ICsJCXNwaW5fbG9ja19pcnFzYXZlKCZiY2hhbi0+dmMubG9j aywgZmxhZyk7DQo+ICsJCXdyaXRlbF9yZWxheGVkKDEsIGJkZXYtPnJlZ3MgKyBCQU1fUF9IQUxU KGJjaGFuLT5pZCkpOw0KPiArCQliY2hhbi0+cGF1c2VkID0gMTsNCj4gKwkJc3Bpbl91bmxvY2tf aXJxcmVzdG9yZSgmYmNoYW4tPnZjLmxvY2ssIGZsYWcpOw0KPiArCQlicmVhazsNCj4gKwljYXNl IERNQV9SRVNVTUU6DQo+ICsJCXNwaW5fbG9ja19pcnFzYXZlKCZiY2hhbi0+dmMubG9jaywgZmxh Zyk7DQo+ICsJCXdyaXRlbF9yZWxheGVkKDAsIGJkZXYtPnJlZ3MgKyBCQU1fUF9IQUxUKGJjaGFu LT5pZCkpOw0KPiArCQliY2hhbi0+cGF1c2VkID0gMDsNCj4gKwkJc3Bpbl91bmxvY2tfaXJxcmVz dG9yZSgmYmNoYW4tPnZjLmxvY2ssIGZsYWcpOw0KPiArCQlicmVhazsNCj4gKwljYXNlIERNQV9U RVJNSU5BVEVfQUxMOg0KPiArCQlzcGluX2xvY2tfaXJxc2F2ZSgmYmNoYW4tPnZjLmxvY2ssIGZs YWcpOw0KPiArCQliYW1fZG1hX3Rlcm1pbmF0ZV9hbGwoY2hhbik7DQo+ICsJCXNwaW5fdW5sb2Nr X2lycXJlc3RvcmUoJmJjaGFuLT52Yy5sb2NrLCBmbGFnKTsNCj4gKwkJYnJlYWs7DQo+ICsJY2Fz ZSBETUFfU0xBVkVfQ09ORklHOg0KPiArCQliYW1fc2xhdmVfY29uZmlnKGJjaGFuLCAoc3RydWN0 IGRtYV9zbGF2ZV9jb25maWcgKilhcmcpOw0KPiArCQlicmVhazsNCj4gKwlkZWZhdWx0Og0KPiAr CQlyZXQgPSAtRU5YSU87DQo+ICsJCWJyZWFrOw0KPiArCX0NCj4gKw0KPiArCXJldHVybiByZXQ7 DQo+ICt9DQo+ICsNCj4gKy8qKg0KPiArICogcHJvY2Vzc19pcnFzX3Blcl9lZSAtIHByb2Nlc3Nl cyB0aGUgaW50ZXJydXB0cyBmb3IgYSBzcGVjaWZpYyBlZQ0KPiArICogQGJkZXY6IGJhbSBjb250 cm9sbGVyDQo+ICsgKiBAZWU6IGV4ZWN1dGlvbiBlbnZpcm9ubWVudA0KPiArICoNCj4gKyAqIFRo aXMgZnVuY3Rpb24gcHJvY2Vzc2VzIHRoZSBpbnRlcnJ1cHRzIGZvciBhIGdpdmVuIGV4ZWN1dGlv biBlbnZpcm9ubWVudA0KPiArICoNCj4gKyAqLw0KPiArc3RhdGljIHUzMiBwcm9jZXNzX2lycXNf cGVyX2VlKHN0cnVjdCBiYW1fZGV2aWNlICpiZGV2LCB1MzIgZWUpDQo+ICt7DQo+ICsJdTMyIGks IHNyY3MsIHBpcGVfc3R0czsNCj4gKwl1bnNpZ25lZCBsb25nIGZsYWdzOw0KPiArCXN0cnVjdCBi YW1fYXN5bmNfZGVzYyAqYXN5bmNfZGVzYzsNCj4gKw0KPiArDQo+ICsJc3JjcyA9IHJlYWRsX3Jl bGF4ZWQoYmRldi0+cmVncyArIEJBTV9JUlFfU1JDU19FRShlZSkpOw0KPiArDQo+ICsJLyogcmV0 dXJuIGVhcmx5IGlmIG5vIHBpcGUvY2hhbm5lbCBpbnRlcnJ1cHRzIGFyZSBwcmVzZW50ICovDQo+ ICsJaWYgKCEoc3JjcyAmIFBfSVJRKSkNCj4gKwkJcmV0dXJuIHNyY3M7DQo+ICsNCj4gKwlmb3Ig KGkgPSAwOyBpIDwgYmRldi0+bnVtX2NoYW5uZWxzOyBpKyspIHsNCj4gKwkJc3RydWN0IGJhbV9j aGFuICpiY2hhbiA9ICZiZGV2LT5jaGFubmVsc1tpXTsNCj4gKwkJaWYgKHNyY3MgJiBCSVQoaSkp IHsNCj4gKwkJCS8qIGNsZWFyIHBpcGUgaXJxICovDQo+ICsJCQlwaXBlX3N0dHMgPSByZWFkbF9y ZWxheGVkKGJkZXYtPnJlZ3MgKw0KPiArCQkJCUJBTV9QX0lSUV9TVFRTKGkpKTsNCj4gKw0KPiAr CQkJd3JpdGVsX3JlbGF4ZWQocGlwZV9zdHRzLCBiZGV2LT5yZWdzICsNCj4gKwkJCQkJQkFNX1Bf SVJRX0NMUihpKSk7DQo+ICsNCj4gKwkJCXNwaW5fbG9ja19pcnFzYXZlKCZiY2hhbi0+dmMubG9j aywgZmxhZ3MpOw0KPiArCQkJYXN5bmNfZGVzYyA9IGJjaGFuLT5jdXJyX3R4ZDsNCj4gKw0KPiAr CQkJaWYgKGFzeW5jX2Rlc2MpIHsNCj4gKwkJCQlhc3luY19kZXNjLT5udW1fZGVzYyAtPSBhc3lu Y19kZXNjLT54ZmVyX2xlbjsNCj4gKwkJCQlhc3luY19kZXNjLT5jdXJyX2Rlc2MgKz0gYXN5bmNf ZGVzYy0+eGZlcl9sZW47DQo+ICsJCQkJYmNoYW4tPmN1cnJfdHhkID0gTlVMTDsNCj4gKw0KPiAr CQkJCS8qIG1hbmFnZSBGSUZPICovDQo+ICsJCQkJYmNoYW4tPmhlYWQgKz0gYXN5bmNfZGVzYy0+ eGZlcl9sZW47DQo+ICsJCQkJYmNoYW4tPmhlYWQgJT0gTUFYX0RFU0NSSVBUT1JTOw0KPiArDQo+ ICsJCQkJLyogaWYgY29tcGxldGUsIHByb2Nlc3MgY29va2llLiAgT3RoZXJ3aXNlDQo+ICsJCQkJ ICAgcHVzaCBiYWNrIHRvIGZyb250IG9mIGRlc2NfaXNzdWVkIHNvIHRoYXQNCj4gKwkJCQkgICBp dCBnZXRzIHJlc3RhcnRlZCBieSB0aGUgdGFza2xldCAqLw0KPiArCQkJCWlmICghYXN5bmNfZGVz Yy0+bnVtX2Rlc2MpDQo+ICsJCQkJCXZjaGFuX2Nvb2tpZV9jb21wbGV0ZSgmYXN5bmNfZGVzYy0+ dmQpOw0KPiArCQkJCWVsc2UNCj4gKwkJCQkJbGlzdF9hZGQoJmFzeW5jX2Rlc2MtPnZkLm5vZGUs DQo+ICsJCQkJCQkmYmNoYW4tPnZjLmRlc2NfaXNzdWVkKTsNCj4gKwkJCX0NCj4gKw0KPiArCQkJ c3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmYmNoYW4tPnZjLmxvY2ssIGZsYWdzKTsNCj4gKwkJfQ0K PiArCX0NCj4gKw0KPiArCXJldHVybiBzcmNzOw0KPiArfQ0KPiArDQo+ICsvKioNCj4gKyAqIGJh bV9kbWFfaXJxIC0gaXJxIGhhbmRsZXIgZm9yIGJhbSBjb250cm9sbGVyDQo+ICsgKiBAaXJxOiBJ UlEgb2YgaW50ZXJydXB0DQo+ICsgKiBAZGF0YTogY2FsbGJhY2sgZGF0YQ0KPiArICoNCj4gKyAq IElSUSBoYW5kbGVyIGZvciB0aGUgYmFtIGNvbnRyb2xsZXINCj4gKyAqLw0KPiArc3RhdGljIGly cXJldHVybl90IGJhbV9kbWFfaXJxKGludCBpcnEsIHZvaWQgKmRhdGEpDQo+ICt7DQo+ICsJc3Ry dWN0IGJhbV9kZXZpY2UgKmJkZXYgPSAoc3RydWN0IGJhbV9kZXZpY2UgKilkYXRhOw0KPiArCXUz MiBjbHJfbWFzayA9IDAsIHNyY3MgPSAwOw0KPiArCXUzMiBpOw0KPiArDQo+ICsNCj4gKwlmb3Ig KGkgPSAwOyBpIDwgYmRldi0+bnVtX2VlczsgaSsrKQ0KPiArCQlpZiAodGVzdF9iaXQoaSwgJmJk ZXYtPmVuYWJsZWRfZWVzKSkNCj4gKwkJCXNyY3MgfD0gcHJvY2Vzc19pcnFzX3Blcl9lZShiZGV2 LCBpKTsNCj4gKw0KPiArCS8qIGtpY2sgb2ZmIHRhc2tsZXQgdG8gc3RhcnQgbmV4dCBkbWEgdHJh bnNmZXIgKi8NCj4gKwlpZiAoc3JjcyAmIFBfSVJRKQ0KPiArCQl0YXNrbGV0X3NjaGVkdWxlKCZi ZGV2LT50YXNrKTsNCj4gKw0KPiArCWlmIChzcmNzICYgQkFNX0lSUSkNCj4gKwkJY2xyX21hc2sg PSByZWFkbF9yZWxheGVkKGJkZXYtPnJlZ3MgKyBCQU1fSVJRX1NUVFMpOw0KPiArDQo+ICsJLyog ZG9uJ3QgYWxsb3cgcmVvcmRlciBvZiB0aGUgdmFyaW91cyBhY2Nlc3NlcyB0byB0aGUgQkFNIHJl Z2lzdGVycyAqLw0KPiArCW1iKCk7DQo+ICsNCj4gKwl3cml0ZWxfcmVsYXhlZChjbHJfbWFzaywg YmRldi0+cmVncyArIEJBTV9JUlFfQ0xSKTsNCj4gKw0KPiArCXJldHVybiBJUlFfSEFORExFRDsN Cj4gK30NCj4gKw0KPiArLyoqDQo+ICsgKiBiYW1fdHhfc3RhdHVzIC0gcmV0dXJucyBzdGF0dXMg b2YgdHJhbnNhY3Rpb24NCj4gKyAqIEBjaGFuOiBkbWEgY2hhbm5lbA0KPiArICogQGNvb2tpZTog dHJhbnNhY3Rpb24gY29va2llDQo+ICsgKiBAdHhzdGF0ZTogRE1BIHRyYW5zYWN0aW9uIHN0YXRl DQo+ICsgKg0KPiArICogUmV0dXJuIHN0YXR1cyBvZiBkbWEgdHJhbnNhY3Rpb24NCj4gKyAqLw0K PiArc3RhdGljIGVudW0gZG1hX3N0YXR1cyBiYW1fdHhfc3RhdHVzKHN0cnVjdCBkbWFfY2hhbiAq Y2hhbiwgZG1hX2Nvb2tpZV90IGNvb2tpZSwNCj4gKwkJc3RydWN0IGRtYV90eF9zdGF0ZSAqdHhz dGF0ZSkNCj4gK3sNCj4gKwlzdHJ1Y3QgYmFtX2NoYW4gKmJjaGFuID0gdG9fYmFtX2NoYW4oY2hh bik7DQo+ICsJc3RydWN0IHZpcnRfZG1hX2Rlc2MgKnZkOw0KPiArCWludCByZXQ7DQo+ICsJc2l6 ZV90IHJlc2lkdWUgPSAwOw0KPiArCXVuc2lnbmVkIGludCBpOw0KPiArCXVuc2lnbmVkIGxvbmcg ZmxhZ3M7DQo+ICsNCj4gKwlyZXQgPSBkbWFfY29va2llX3N0YXR1cyhjaGFuLCBjb29raWUsIHR4 c3RhdGUpOw0KPiArDQoNClJlZHVuZGFudCBlbXB0eSBsaW5lLg0KDQo+ICsJaWYgKHJldCA9PSBE TUFfQ09NUExFVEUpDQo+ICsJCXJldHVybiByZXQ7DQo+ICsNCj4gKwlpZiAoIXR4c3RhdGUpDQo+ ICsJCXJldHVybiBiY2hhbi0+cGF1c2VkID8gRE1BX1BBVVNFRCA6IHJldDsNCj4gKw0KPiArCXNw aW5fbG9ja19pcnFzYXZlKCZiY2hhbi0+dmMubG9jaywgZmxhZ3MpOw0KPiArCXZkID0gdmNoYW5f ZmluZF9kZXNjKCZiY2hhbi0+dmMsIGNvb2tpZSk7DQo+ICsJaWYgKHZkKQ0KPiArCQlyZXNpZHVl ID0gY29udGFpbmVyX29mKHZkLCBzdHJ1Y3QgYmFtX2FzeW5jX2Rlc2MsIHZkKS0+bGVuZ3RoOw0K PiArCWVsc2UgaWYgKGJjaGFuLT5jdXJyX3R4ZCAmJiBiY2hhbi0+Y3Vycl90eGQtPnZkLnR4LmNv b2tpZSA9PSBjb29raWUpDQo+ICsJCWZvciAoaSA9IDA7IGkgPCBiY2hhbi0+Y3Vycl90eGQtPm51 bV9kZXNjOyBpKyspDQo+ICsJCQlyZXNpZHVlICs9IGJjaGFuLT5jdXJyX3R4ZC0+Y3Vycl9kZXNj W2ldLnNpemU7DQo+ICsNCj4gKwlkbWFfc2V0X3Jlc2lkdWUodHhzdGF0ZSwgcmVzaWR1ZSk7DQoN CkknbSBwcmV0dHkgc3VyZSB5b3UgY291bGQgZG8gdGhpcyBvdXRzaWRlIG9mIHNwaW4gbG9jay4N Cg0KPiArDQo+ICsJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmYmNoYW4tPnZjLmxvY2ssIGZsYWdz KTsNCj4gKw0KPiArCWlmIChyZXQgPT0gRE1BX0lOX1BST0dSRVNTICYmIGJjaGFuLT5wYXVzZWQp DQo+ICsJCXJldCA9IERNQV9QQVVTRUQ7DQo+ICsNCj4gKwlyZXR1cm4gcmV0Ow0KPiArfQ0KPiAr DQo+ICsvKioNCj4gKyAqIGJhbV9zdGFydF9kbWEgLSBzdGFydCBuZXh0IHRyYW5zYWN0aW9uDQo+ ICsgKiBAYmNoYW4gLSBiYW0gZG1hIGNoYW5uZWwNCj4gKyAqDQo+ICsgKiBOb3RlOiBtdXN0IGhv bGQgYmFtIGRtYSBjaGFubmVsIHZjLmxvY2sNCj4gKyAqLw0KPiArc3RhdGljIHZvaWQgYmFtX3N0 YXJ0X2RtYShzdHJ1Y3QgYmFtX2NoYW4gKmJjaGFuKQ0KPiArew0KPiArCXN0cnVjdCB2aXJ0X2Rt YV9kZXNjICp2ZCA9IHZjaGFuX25leHRfZGVzYygmYmNoYW4tPnZjKTsNCj4gKwlzdHJ1Y3QgYmFt X2RldmljZSAqYmRldiA9IGJjaGFuLT5iZGV2Ow0KPiArCXN0cnVjdCBiYW1fYXN5bmNfZGVzYyAq YXN5bmNfZGVzYzsNCj4gKwlzdHJ1Y3QgYmFtX2Rlc2NfaHcgKmRlc2M7DQo+ICsJc3RydWN0IGJh bV9kZXNjX2h3ICpmaWZvID0gUFRSX0FMSUdOKGJjaGFuLT5maWZvX3ZpcnQsDQo+ICsJCQkJc2l6 ZW9mKHN0cnVjdCBiYW1fZGVzY19odykpOw0KDQo+ICsNCj4gKwlpZiAoIXZkKQ0KPiArCQlyZXR1 cm47DQo+ICsNCj4gKwlsaXN0X2RlbCgmdmQtPm5vZGUpOw0KPiArDQo+ICsJYXN5bmNfZGVzYyA9 IGNvbnRhaW5lcl9vZih2ZCwgc3RydWN0IGJhbV9hc3luY19kZXNjLCB2ZCk7DQo+ICsJYmNoYW4t PmN1cnJfdHhkID0gYXN5bmNfZGVzYzsNCj4gKw0KPiArCWRlc2MgPSBiY2hhbi0+Y3Vycl90eGQt PmN1cnJfZGVzYzsNCj4gKw0KPiArCWlmIChhc3luY19kZXNjLT5udW1fZGVzYyA+IE1BWF9ERVND UklQVE9SUykNCj4gKwkJYXN5bmNfZGVzYy0+eGZlcl9sZW4gPSBNQVhfREVTQ1JJUFRPUlM7DQo+ ICsJZWxzZQ0KPiArCQlhc3luY19kZXNjLT54ZmVyX2xlbiA9IGFzeW5jX2Rlc2MtPm51bV9kZXNj Ow0KPiArDQo+ICsJLyogc2V0IElOVCBvbiBsYXN0IGRlc2NyaXB0b3IgKi8NCj4gKwlkZXNjW2Fz eW5jX2Rlc2MtPnhmZXJfbGVuIC0gMV0uZmxhZ3MgfD0gREVTQ19GTEFHX0lOVDsNCj4gKw0KPiAr CWlmIChiY2hhbi0+dGFpbCArIGFzeW5jX2Rlc2MtPnhmZXJfbGVuID4gTUFYX0RFU0NSSVBUT1JT KSB7DQo+ICsJCXUzMiBwYXJ0aWFsID0gTUFYX0RFU0NSSVBUT1JTIC0gYmNoYW4tPnRhaWw7DQo+ ICsNCj4gKwkJbWVtY3B5KCZmaWZvW2JjaGFuLT50YWlsXSwgZGVzYywNCj4gKwkJCQlwYXJ0aWFs ICogc2l6ZW9mKHN0cnVjdCBiYW1fZGVzY19odykpOw0KPiArCQltZW1jcHkoZmlmbywgJmRlc2Nb cGFydGlhbF0sIChhc3luY19kZXNjLT54ZmVyX2xlbiAtIHBhcnRpYWwpICoNCj4gKwkJCQlzaXpl b2Yoc3RydWN0IGJhbV9kZXNjX2h3KSk7DQoNCkknbSBqdXN0IGN1cmlvdXMgaWYgeW91IGNvdWxk IGF2b2lkIG1lbWNweXMgYXQgYWxsIHNvbWVob3cuDQoNCj4gKwl9IGVsc2UNCg0KS2VlcCBzdHls ZQ0KDQp9IGVsc2Ugew0KLi4uDQp9DQoNCkhhdmUgeW91IHJ1biBjaGVja3BhdGNoLnBsPw0KDQo+ ICsJCW1lbWNweSgmZmlmb1tiY2hhbi0+dGFpbF0sIGRlc2MsDQo+ICsJCQlhc3luY19kZXNjLT54 ZmVyX2xlbiAqIHNpemVvZihzdHJ1Y3QgYmFtX2Rlc2NfaHcpKTsNCj4gKw0KPiArCWJjaGFuLT50 YWlsICs9IGFzeW5jX2Rlc2MtPnhmZXJfbGVuOw0KPiArCWJjaGFuLT50YWlsICU9IE1BWF9ERVND UklQVE9SUzsNCj4gKw0KPiArCS8qIGVuc3VyZSBkZXNjcmlwdG9yIHdyaXRlcyBhbmQgZG1hIHN0 YXJ0IG5vdCByZW9yZGVyZWQgKi8NCj4gKwl3bWIoKTsNCj4gKwl3cml0ZWxfcmVsYXhlZChiY2hh bi0+dGFpbCAqIHNpemVvZihzdHJ1Y3QgYmFtX2Rlc2NfaHcpLA0KPiArCQkJYmRldi0+cmVncyAr IEJBTV9QX0VWTlRfUkVHKGJjaGFuLT5pZCkpOw0KPiArfQ0KPiArDQo+ICsvKioNCj4gKyAqIGRt YV90YXNrbGV0IC0gRE1BIElSUSB0YXNrbGV0DQo+ICsgKiBAZGF0YTogdGFza2xldCBhcmd1bWVu dCAoYmFtIGNvbnRyb2xsZXIgc3RydWN0dXJlKQ0KPiArICoNCj4gKyAqIFNldHMgdXAgbmV4dCBE TUEgb3BlcmF0aW9uIGFuZCB0aGVuIHByb2Nlc3NlcyBhbGwgY29tcGxldGVkIHRyYW5zYWN0aW9u cw0KPiArICovDQo+ICtzdGF0aWMgdm9pZCBkbWFfdGFza2xldCh1bnNpZ25lZCBsb25nIGRhdGEp DQo+ICt7DQo+ICsJc3RydWN0IGJhbV9kZXZpY2UgKmJkZXYgPSAoc3RydWN0IGJhbV9kZXZpY2Ug KilkYXRhOw0KPiArCXN0cnVjdCBiYW1fY2hhbiAqYmNoYW47DQo+ICsJdW5zaWduZWQgbG9uZyBm bGFnczsNCj4gKwl1bnNpZ25lZCBpbnQgaTsNCj4gKw0KPiArCS8qIGdvIHRocm91Z2ggdGhlIGNo YW5uZWxzIGFuZCBraWNrIG9mZiB0cmFuc2FjdGlvbnMgKi8NCj4gKwlmb3IgKGkgPSAwOyBpIDwg YmRldi0+bnVtX2NoYW5uZWxzOyBpKyspIHsNCj4gKwkJYmNoYW4gPSAmYmRldi0+Y2hhbm5lbHNb aV07DQo+ICsJCXNwaW5fbG9ja19pcnFzYXZlKCZiY2hhbi0+dmMubG9jaywgZmxhZ3MpOw0KPiAr DQo+ICsJCWlmICghbGlzdF9lbXB0eSgmYmNoYW4tPnZjLmRlc2NfaXNzdWVkKSAmJiAhYmNoYW4t PmN1cnJfdHhkKQ0KPiArCQkJYmFtX3N0YXJ0X2RtYShiY2hhbik7DQo+ICsJCXNwaW5fdW5sb2Nr X2lycXJlc3RvcmUoJmJjaGFuLT52Yy5sb2NrLCBmbGFncyk7DQo+ICsJfQ0KPiArfQ0KPiArDQo+ ICsvKioNCj4gKyAqIGJhbV9pc3N1ZV9wZW5kaW5nIC0gc3RhcnRzIHBlbmRpbmcgdHJhbnNhY3Rp b25zDQo+ICsgKiBAY2hhbjogZG1hIGNoYW5uZWwNCj4gKyAqDQo+ICsgKiBDYWxscyB0YXNrbGV0 IGRpcmVjdGx5IHdoaWNoIGluIHR1cm4gc3RhcnRzIGFueSBwZW5kaW5nIHRyYW5zYWN0aW9ucw0K PiArICovDQo+ICtzdGF0aWMgdm9pZCBiYW1faXNzdWVfcGVuZGluZyhzdHJ1Y3QgZG1hX2NoYW4g KmNoYW4pDQo+ICt7DQo+ICsJc3RydWN0IGJhbV9jaGFuICpiY2hhbiA9IHRvX2JhbV9jaGFuKGNo YW4pOw0KPiArCXVuc2lnbmVkIGxvbmcgZmxhZ3M7DQo+ICsNCj4gKwlzcGluX2xvY2tfaXJxc2F2 ZSgmYmNoYW4tPnZjLmxvY2ssIGZsYWdzKTsNCj4gKw0KPiArCS8qIGlmIHdvcmsgcGVuZGluZyBh bmQgaWRsZSwgc3RhcnQgYSB0cmFuc2FjdGlvbiAqLw0KPiArCWlmICh2Y2hhbl9pc3N1ZV9wZW5k aW5nKCZiY2hhbi0+dmMpICYmICFiY2hhbi0+Y3Vycl90eGQpDQo+ICsJCWJhbV9zdGFydF9kbWEo YmNoYW4pOw0KPiArDQo+ICsJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmYmNoYW4tPnZjLmxvY2ss IGZsYWdzKTsNCj4gK30NCj4gKw0KPiArLyoqDQo+ICsgKiBiYW1fZG1hX2ZyZWVfZGVzYyAtIGZy ZWUgZGVzY3JpcHRvciBtZW1vcnkNCj4gKyAqIEB2ZDogdmlydHVhbCBkZXNjcmlwdG9yDQo+ICsg Kg0KPiArICovDQo+ICtzdGF0aWMgdm9pZCBiYW1fZG1hX2ZyZWVfZGVzYyhzdHJ1Y3QgdmlydF9k bWFfZGVzYyAqdmQpDQo+ICt7DQo+ICsJc3RydWN0IGJhbV9hc3luY19kZXNjICphc3luY19kZXNj ID0gY29udGFpbmVyX29mKHZkLA0KPiArCQkJc3RydWN0IGJhbV9hc3luY19kZXNjLCB2ZCk7DQo+ ICsNCj4gKwlrZnJlZShhc3luY19kZXNjKTsNCj4gK30NCj4gKw0KPiArc3RydWN0IGJhbV9maWx0 ZXJfYXJncyB7DQo+ICsJc3RydWN0IGRtYV9kZXZpY2UgKmRldjsNCj4gKwl1MzIgaWQ7DQo+ICsJ dTMyIGVlOw0KPiArCXUzMiBkaXI7DQo+ICt9Ow0KPiArDQo+ICtzdGF0aWMgYm9vbCBiYW1fZG1h X2ZpbHRlcihzdHJ1Y3QgZG1hX2NoYW4gKmNoYW4sIHZvaWQgKmRhdGEpDQo+ICt7DQo+ICsJc3Ry dWN0IGJhbV9maWx0ZXJfYXJncyAqYXJncyA9IGRhdGE7DQo+ICsJc3RydWN0IGJhbV9jaGFuICpi Y2hhbiA9IHRvX2JhbV9jaGFuKGNoYW4pOw0KPiArDQo+ICsJaWYgKGFyZ3MtPmRldiA9PSBjaGFu LT5kZXZpY2UgJiYNCj4gKwkJYXJncy0+aWQgPT0gYmNoYW4tPmlkKSB7DQo+ICsNCj4gKwkJLyog d2UgZm91bmQgdGhlIGNoYW5uZWwsIHNvIGxldHMgc2V0IHRoZSBFRSBhbmQgZGlyICovDQo+ICsJ CWJjaGFuLT5lZSA9IGFyZ3MtPmVlOw0KPiArCQliY2hhbi0+c2xhdmUuZGlyZWN0aW9uID0gYXJn cy0+ZGlyID8NCj4gKwkJCQlETUFfREVWX1RPX01FTSA6IERNQV9NRU1fVE9fREVWOw0KPiArCQly ZXR1cm4gdHJ1ZTsNCj4gKwl9DQo+ICsNCj4gKwlyZXR1cm4gZmFsc2U7DQo+ICt9DQo+ICsNCj4g K3N0YXRpYyBzdHJ1Y3QgZG1hX2NoYW4gKmJhbV9kbWFfeGxhdGUoc3RydWN0IG9mX3BoYW5kbGVf YXJncyAqZG1hX3NwZWMsDQo+ICsJCXN0cnVjdCBvZl9kbWEgKm9mKQ0KPiArew0KPiArCXN0cnVj dCBiYW1fZmlsdGVyX2FyZ3MgYXJnczsNCj4gKwlkbWFfY2FwX21hc2tfdCBjYXA7DQo+ICsNCj4g KwlpZiAoZG1hX3NwZWMtPmFyZ3NfY291bnQgIT0gMykNCj4gKwkJcmV0dXJuIE5VTEw7DQo+ICsN Cj4gKwlhcmdzLmRldiA9IG9mLT5vZl9kbWFfZGF0YTsNCj4gKwlhcmdzLmlkID0gZG1hX3NwZWMt PmFyZ3NbMF07DQo+ICsJYXJncy5lZSA9IGRtYV9zcGVjLT5hcmdzWzFdOw0KPiArCWFyZ3MuZGly ID0gZG1hX3NwZWMtPmFyZ3NbMl07DQo+ICsNCj4gKwlkbWFfY2FwX3plcm8oY2FwKTsNCj4gKwlk bWFfY2FwX3NldChETUFfU0xBVkUsIGNhcCk7DQo+ICsNCj4gKwlyZXR1cm4gZG1hX3JlcXVlc3Rf Y2hhbm5lbChjYXAsIGJhbV9kbWFfZmlsdGVyLCAmYXJncyk7DQo+ICt9DQo+ICsNCj4gKy8qKg0K PiArICogYmFtX2luaXQNCj4gKyAqIEBiZGV2OiBiYW0gZGV2aWNlDQo+ICsgKg0KPiArICogSW5p dGlhbGl6YXRpb24gaGVscGVyIGZvciBnbG9iYWwgYmFtIHJlZ2lzdGVycw0KPiArICovDQo+ICtz dGF0aWMgdm9pZCBiYW1faW5pdChzdHJ1Y3QgYmFtX2RldmljZSAqYmRldikNCj4gK3sNCj4gKwl1 MzIgdmFsOw0KPiArDQo+ICsJLyogcmVhZCB2ZXJzaW9uaW5nIGluZm9ybWF0aW9uICovDQo+ICsJ dmFsID0gcmVhZGxfcmVsYXhlZChiZGV2LT5yZWdzICsgQkFNX1JFVklTSU9OKTsNCj4gKwliZGV2 LT5udW1fZWVzID0gdmFsICYgTlVNX0VFU19NQVNLOw0KPiArDQo+ICsJdmFsID0gcmVhZGxfcmVs YXhlZChiZGV2LT5yZWdzICsgQkFNX05VTV9QSVBFUyk7DQo+ICsJYmRldi0+bnVtX2NoYW5uZWxz ID0gdmFsICYgQkFNX05VTV9QSVBFU19NQVNLOw0KPiArDQo+ICsJLyogcy93IHJlc2V0IGJhbSAq Lw0KPiArCS8qIGFmdGVyIHJlc2V0IGFsbCBwaXBlcyBhcmUgZGlzYWJsZWQgYW5kIGlkbGUgKi8N Cj4gKwl2YWwgPSByZWFkbF9yZWxheGVkKGJkZXYtPnJlZ3MgKyBCQU1fQ1RSTCk7DQo+ICsJdmFs IHw9IEJBTV9TV19SU1Q7DQo+ICsJd3JpdGVsX3JlbGF4ZWQodmFsLCBiZGV2LT5yZWdzICsgQkFN X0NUUkwpOw0KPiArCXZhbCAmPSB+QkFNX1NXX1JTVDsNCj4gKwl3cml0ZWxfcmVsYXhlZCh2YWws IGJkZXYtPnJlZ3MgKyBCQU1fQ1RSTCk7DQo+ICsNCj4gKwkvKiBtYWtlIHN1cmUgcHJldmlvdXMg c3RvcmVzIGFyZSB2aXNpYmxlIGJlZm9yZSBlbmFibGluZyBCQU0gKi8NCj4gKwl3bWIoKTsNCj4g Kw0KPiArCS8qIGVuYWJsZSBiYW0gKi8NCj4gKwl2YWwgfD0gQkFNX0VOOw0KPiArCXdyaXRlbF9y ZWxheGVkKHZhbCwgYmRldi0+cmVncyArIEJBTV9DVFJMKTsNCj4gKw0KPiArCS8qIHNldCBkZXNj cmlwdG9yIHRocmVzaGhvbGQsIHN0YXJ0IHdpdGggNCBieXRlcyAqLw0KPiArCXdyaXRlbF9yZWxh eGVkKERFRkFVTFRfQ05UX1RIUlNITEQsIGJkZXYtPnJlZ3MgKyBCQU1fREVTQ19DTlRfVFJTSExE KTsNCj4gKw0KPiArCS8qIEVuYWJsZSBkZWZhdWx0IHNldCBvZiBoL3cgd29ya2Fyb3VuZHMsIGll IGFsbCBleGNlcHQgQkFNX0ZVTExfUElQRSAqLw0KPiArCXdyaXRlbF9yZWxheGVkKEJBTV9DTkZH X0JJVFNfREVGQVVMVCwgYmRldi0+cmVncyArIEJBTV9DTkZHX0JJVFMpOw0KPiArDQo+ICsJLyog ZW5hYmxlIGlycXMgZm9yIGVycm9ycyAqLw0KPiArCXdyaXRlbF9yZWxheGVkKEJBTV9FUlJPUl9F TiB8IEJBTV9IUkVTUF9FUlJfRU4sDQo+ICsJCQkJYmRldi0+cmVncyArIEJBTV9JUlFfRU4pOw0K PiArfQ0KPiArDQo+ICtzdGF0aWMgdm9pZCBiYW1fY2hhbm5lbF9pbml0KHN0cnVjdCBiYW1fZGV2 aWNlICpiZGV2LCBzdHJ1Y3QgYmFtX2NoYW4gKmJjaGFuLA0KPiArCXUzMiBpbmRleCkNCj4gK3sN Cj4gKwliY2hhbi0+aWQgPSBpbmRleDsNCj4gKwliY2hhbi0+YmRldiA9IGJkZXY7DQo+ICsNCj4g Kwl2Y2hhbl9pbml0KCZiY2hhbi0+dmMsICZiZGV2LT5jb21tb24pOw0KPiArCWJjaGFuLT52Yy5k ZXNjX2ZyZWUgPSBiYW1fZG1hX2ZyZWVfZGVzYzsNCj4gKw0KPiArCWJhbV9yZXNldF9jaGFubmVs KGJkZXYsIGJjaGFuLT5pZCk7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyBpbnQgYmFtX2RtYV9wcm9i ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQ0KPiArew0KPiArCXN0cnVjdCBiYW1fZGV2 aWNlICpiZGV2Ow0KPiArCXN0cnVjdCByZXNvdXJjZSAqaW9yZXMsICppcnFfcmVzOw0KPiArCWlu dCByZXQsIGk7DQo+ICsNCj4gKwliZGV2ID0gZGV2bV9remFsbG9jKCZwZGV2LT5kZXYsIHNpemVv ZigqYmRldiksIEdGUF9LRVJORUwpOw0KPiArCWlmICghYmRldikNCj4gKwkJcmV0dXJuIC1FTk9N RU07DQo+ICsNCj4gKwliZGV2LT5kZXYgPSAmcGRldi0+ZGV2Ow0KPiArDQo+ICsJaW9yZXMgPSBw bGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDApOw0KPiArCWlmICgh aW9yZXMpIHsNCj4gKwkJZGV2X2VycihiZGV2LT5kZXYsICJyZWdpc3RlciByZXNvdXJjZSBpcyBt aXNzaW5nXG4iKTsNCj4gKwkJcmV0dXJuIC1FSU5WQUw7DQo+ICsJfQ0KDQpVc2VsZXNzIGNoZWNr IGFuZCBtZXNzYWdpbmcsIGRldm1faW9yZW1hcF9yZXNvdXJjZSB3aWxsIGRvIHRoaXMgZm9yIHlv dS4NCg0KPiArDQo+ICsJYmRldi0+cmVncyA9IGRldm1faW9yZW1hcF9yZXNvdXJjZSgmcGRldi0+ ZGV2LCBpb3Jlcyk7DQo+ICsJaWYgKElTX0VSUihiZGV2LT5yZWdzKSkNCj4gKwkJcmV0dXJuIFBU Ul9FUlIoYmRldi0+cmVncyk7DQo+ICsNCj4gKwlpcnFfcmVzID0gcGxhdGZvcm1fZ2V0X3Jlc291 cmNlKHBkZXYsIElPUkVTT1VSQ0VfSVJRLCAwKTsNCj4gKwlpZiAoIWlycV9yZXMpIHsNCj4gKwkJ ZGV2X2VycihiZGV2LT5kZXYsICJpcnEgcmVzb3VyY2UgaXMgbWlzc2luZ1xuIik7DQo+ICsJCXJl dHVybiAtRUlOVkFMOw0KPiArCX0NCj4gKw0KPiArCWJkZXYtPmJhbWNsayA9IGRldm1fY2xrX2dl dChiZGV2LT5kZXYsICJiYW1fY2xrIik7DQo+ICsJaWYgKElTX0VSUihiZGV2LT5iYW1jbGspKQ0K PiArCQlyZXR1cm4gUFRSX0VSUihiZGV2LT5iYW1jbGspOw0KPiArDQo+ICsJcmV0ID0gY2xrX3By ZXBhcmVfZW5hYmxlKGJkZXYtPmJhbWNsayk7DQo+ICsJaWYgKHJldCkgew0KPiArCQlkZXZfZXJy KGJkZXYtPmRldiwgImZhaWxlZCB0byBwcmVwYXJlL2VuYWJsZSBjbG9jayIpOw0KPiArCQlyZXR1 cm4gcmV0Ow0KPiArCX0NCj4gKw0KPiArCWJhbV9pbml0KGJkZXYpOw0KPiArDQo+ICsJdGFza2xl dF9pbml0KCZiZGV2LT50YXNrLCBkbWFfdGFza2xldCwgKHVuc2lnbmVkIGxvbmcpYmRldik7DQo+ ICsNCj4gKwliZGV2LT5jaGFubmVscyA9IGRldm1fa3phbGxvYyhiZGV2LT5kZXYsDQoNCmRldm1f a2NhbGxvYy4NCg0KPiArCQkJCXNpemVvZigqYmRldi0+Y2hhbm5lbHMpICogYmRldi0+bnVtX2No YW5uZWxzLA0KPiArCQkJCUdGUF9LRVJORUwpOw0KPiArDQo+ICsJaWYgKCFiZGV2LT5jaGFubmVs cykgew0KPiArCQlyZXQgPSAtRU5PTUVNOw0KPiArCQlnb3RvIGVycl9kaXNhYmxlX2NsazsNCj4g Kwl9DQo+ICsNCj4gKwkvKiBhbGxvY2F0ZSBhbmQgaW5pdGlhbGl6ZSBjaGFubmVscyAqLw0KPiAr CUlOSVRfTElTVF9IRUFEKCZiZGV2LT5jb21tb24uY2hhbm5lbHMpOw0KPiArDQo+ICsJZm9yIChp ID0gMDsgaSA8IGJkZXYtPm51bV9jaGFubmVsczsgaSsrKQ0KPiArCQliYW1fY2hhbm5lbF9pbml0 KGJkZXYsICZiZGV2LT5jaGFubmVsc1tpXSwgaSk7DQo+ICsNCj4gKwlyZXQgPSBkZXZtX3JlcXVl c3RfaXJxKGJkZXYtPmRldiwgaXJxX3Jlcy0+c3RhcnQsIGJhbV9kbWFfaXJxLA0KPiArCQkJSVJR Rl9UUklHR0VSX0hJR0gsICJiYW1fZG1hIiwgYmRldik7DQo+ICsJaWYgKHJldCkgew0KPiArCQlk ZXZfZXJyKGJkZXYtPmRldiwgImNhbm5vdCByZWdpc3RlciBJUlFcbiIpOw0KPiArCQlnb3RvIGVy cl9kaXNhYmxlX2NsazsNCj4gKwl9DQo+ICsNCj4gKwkvKiBzZXQgbWF4IGRtYSBzZWdtZW50IHNp emUgKi8NCj4gKwliZGV2LT5jb21tb24uZGV2ID0gYmRldi0+ZGV2Ow0KPiArCWJkZXYtPmNvbW1v bi5kZXYtPmRtYV9wYXJtcyA9ICZiZGV2LT5kbWFfcGFybXM7DQo+ICsJcmV0ID0gZG1hX3NldF9t YXhfc2VnX3NpemUoYmRldi0+Y29tbW9uLmRldiwgQkFNX01BWF9EQVRBX1NJWkUpOw0KPiArCWlm IChyZXQpIHsNCj4gKwkJZGV2X2VycihiZGV2LT5kZXYsICJjYW5ub3Qgc2V0IG1heGltdW0gc2Vn bWVudCBzaXplXG4iKTsNCj4gKwkJZ290byBlcnJfZGlzYWJsZV9jbGs7DQo+ICsJfQ0KPiArDQo+ ICsJcGxhdGZvcm1fc2V0X2RydmRhdGEocGRldiwgYmRldik7DQo+ICsNCj4gKwkvKiBzZXQgY2Fw YWJpbGl0aWVzICovDQo+ICsJZG1hX2NhcF96ZXJvKGJkZXYtPmNvbW1vbi5jYXBfbWFzayk7DQo+ ICsJZG1hX2NhcF9zZXQoRE1BX1NMQVZFLCBiZGV2LT5jb21tb24uY2FwX21hc2spOw0KPiArDQo+ ICsJLyogaW5pdGlhbGl6ZSBkbWFlbmdpbmUgYXBpcyAqLw0KPiArCWJkZXYtPmNvbW1vbi5kZXZp Y2VfYWxsb2NfY2hhbl9yZXNvdXJjZXMgPSBiYW1fYWxsb2NfY2hhbjsNCj4gKwliZGV2LT5jb21t b24uZGV2aWNlX2ZyZWVfY2hhbl9yZXNvdXJjZXMgPSBiYW1fZnJlZV9jaGFuOw0KPiArCWJkZXYt PmNvbW1vbi5kZXZpY2VfcHJlcF9zbGF2ZV9zZyA9IGJhbV9wcmVwX3NsYXZlX3NnOw0KPiArCWJk ZXYtPmNvbW1vbi5kZXZpY2VfY29udHJvbCA9IGJhbV9jb250cm9sOw0KPiArCWJkZXYtPmNvbW1v bi5kZXZpY2VfaXNzdWVfcGVuZGluZyA9IGJhbV9pc3N1ZV9wZW5kaW5nOw0KPiArCWJkZXYtPmNv bW1vbi5kZXZpY2VfdHhfc3RhdHVzID0gYmFtX3R4X3N0YXR1czsNCj4gKwliZGV2LT5jb21tb24u ZGV2ID0gYmRldi0+ZGV2Ow0KPiArDQo+ICsJcmV0ID0gZG1hX2FzeW5jX2RldmljZV9yZWdpc3Rl cigmYmRldi0+Y29tbW9uKTsNCj4gKwlpZiAocmV0KSB7DQo+ICsJCWRldl9lcnIoYmRldi0+ZGV2 LCAiZmFpbGVkIHRvIHJlZ2lzdGVyIGRtYSBhc3luYyBkZXZpY2VcbiIpOw0KPiArCQlnb3RvIGVy cl9kaXNhYmxlX2NsazsNCj4gKwl9DQo+ICsNCj4gKwlpZiAocGRldi0+ZGV2Lm9mX25vZGUpIHsN Cj4gKwkJcmV0ID0gb2ZfZG1hX2NvbnRyb2xsZXJfcmVnaXN0ZXIocGRldi0+ZGV2Lm9mX25vZGUs DQo+ICsJCQkJYmFtX2RtYV94bGF0ZSwgJmJkZXYtPmNvbW1vbik7DQo+ICsNCj4gKwkJaWYgKHJl dCkgew0KPiArCQkJZGV2X2VycihiZGV2LT5kZXYsICJmYWlsZWQgdG8gcmVnaXN0ZXIgb2ZfZG1h XG4iKTsNCj4gKwkJCWdvdG8gZXJyX3VucmVnaXN0ZXJfZG1hOw0KPiArCQl9DQo+ICsJfQ0KPiAr DQo+ICsJcmV0dXJuIDA7DQo+ICsNCj4gK2Vycl91bnJlZ2lzdGVyX2RtYToNCj4gKwlkbWFfYXN5 bmNfZGV2aWNlX3VucmVnaXN0ZXIoJmJkZXYtPmNvbW1vbik7DQo+ICtlcnJfZGlzYWJsZV9jbGs6 DQo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKGJkZXYtPmJhbWNsayk7DQoNCg0KDQo+ICsJcmV0 dXJuIHJldDsNCj4gK30NCj4gKw0KPiArc3RhdGljIGludCBiYW1fZG1hX3JlbW92ZShzdHJ1Y3Qg cGxhdGZvcm1fZGV2aWNlICpwZGV2KQ0KPiArew0KPiArCXN0cnVjdCBiYW1fZGV2aWNlICpiZGV2 ID0gcGxhdGZvcm1fZ2V0X2RydmRhdGEocGRldik7DQo+ICsNCj4gKwlkbWFfYXN5bmNfZGV2aWNl X3VucmVnaXN0ZXIoJmJkZXYtPmNvbW1vbik7DQo+ICsNCj4gKwlpZiAocGRldi0+ZGV2Lm9mX25v ZGUpDQo+ICsJCW9mX2RtYV9jb250cm9sbGVyX2ZyZWUocGRldi0+ZGV2Lm9mX25vZGUpOw0KPiAr DQo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKGJkZXYtPmJhbWNsayk7DQo+ICsNCj4gKwlyZXR1 cm4gMDsNCj4gK30NCj4gKw0KPiArI2lmZGVmIENPTkZJR19PRg0KPiArc3RhdGljIGNvbnN0IHN0 cnVjdCBvZl9kZXZpY2VfaWQgYmFtX29mX21hdGNoW10gPSB7DQo+ICsJeyAuY29tcGF0aWJsZSA9 ICJxY29tLGJhbS12MS40LjAiLCB9LA0KPiArCXsgLmNvbXBhdGlibGUgPSAicWNvbSxiYW0tdjEu NC4xIiwgfSwNCj4gKwl7fQ0KPiArfTsNCj4gK01PRFVMRV9ERVZJQ0VfVEFCTEUob2YsIGJhbV9v Zl9tYXRjaCk7DQo+ICsjZW5kaWYNCj4gKw0KPiArc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2 ZXIgYmFtX2RtYV9kcml2ZXIgPSB7DQo+ICsJLnByb2JlID0gYmFtX2RtYV9wcm9iZSwNCj4gKwku cmVtb3ZlID0gYmFtX2RtYV9yZW1vdmUsDQo+ICsJLmRyaXZlciA9IHsNCj4gKwkJLm5hbWUgPSAi YmFtLWRtYS1lbmdpbmUiLA0KPiArCQkub3duZXIgPSBUSElTX01PRFVMRSwNCj4gKwkJLm9mX21h dGNoX3RhYmxlID0gb2ZfbWF0Y2hfcHRyKGJhbV9vZl9tYXRjaCksDQo+ICsJfSwNCj4gK307DQo+ ICsNCj4gK3N0YXRpYyBpbnQgX19pbml0IGJhbV9kbWFfaW5pdCh2b2lkKQ0KPiArew0KPiArCXJl dHVybiBwbGF0Zm9ybV9kcml2ZXJfcmVnaXN0ZXIoJmJhbV9kbWFfZHJpdmVyKTsNCj4gK30NCj4g Kw0KPiArc3RhdGljIHZvaWQgX19leGl0IGJhbV9kbWFfZXhpdCh2b2lkKQ0KPiArew0KPiArCXJl dHVybiBwbGF0Zm9ybV9kcml2ZXJfdW5yZWdpc3RlcigmYmFtX2RtYV9kcml2ZXIpOw0KPiArfQ0K PiArDQo+ICttb2R1bGVfaW5pdChiYW1fZG1hX2luaXQpOw0KPiArbW9kdWxlX2V4aXQoYmFtX2Rt YV9leGl0KTsNCg0KbW9kdWxlX3BsYXRmb3JtX2RyaXZlcigpID8NCg0KPiArDQo+ICtNT0RVTEVf QVVUSE9SKCJBbmR5IEdyb3NzIDxhZ3Jvc3NAY29kZWF1cm9yYS5vcmc+Iik7DQo+ICtNT0RVTEVf REVTQ1JJUFRJT04oIlFDT00gQkFNIERNQSBlbmdpbmUgZHJpdmVyIik7DQo+ICtNT0RVTEVfTElD RU5TRSgiR1BMIHYyIik7DQo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2RtYS9xY29tX2JhbV9kbWEu aCBiL2RyaXZlcnMvZG1hL3Fjb21fYmFtX2RtYS5oDQo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+ IGluZGV4IDAwMDAwMDAuLjJjYjNiNWYNCj4gLS0tIC9kZXYvbnVsbA0KPiArKysgYi9kcml2ZXJz L2RtYS9xY29tX2JhbV9kbWEuaA0KPiBAQCAtMCwwICsxLDI2OCBAQA0KPiArLyoNCj4gKyAqIENv cHlyaWdodCAoYykgMjAxMywgVGhlIExpbnV4IEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2 ZWQuDQoNCjIwMTQgPw0KDQo+ICsgKg0KPiArICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdh cmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkNCj4gKyAqIGl0IHVuZGVy IHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIGFu ZA0KPiArICogb25seSB2ZXJzaW9uIDIgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJl IEZvdW5kYXRpb24uDQo+ICsgKg0KPiArICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGlu IHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsDQo+ICsgKiBidXQgV0lUSE9VVCBBTlkg V0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZg0KPiArICogTUVS Q0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRo ZQ0KPiArICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4NCj4g KyAqLw0KPiArI2lmbmRlZiBfX1FDT01fQkFNX0RNQV9IX18NCj4gKyNkZWZpbmUgX19RQ09NX0JB TV9ETUFfSF9fDQo+ICsNCj4gKyNpbmNsdWRlIDxsaW51eC9kbWFlbmdpbmUuaD4NCj4gKyNpbmNs dWRlICJ2aXJ0LWRtYS5oIg0KPiArDQo+ICtlbnVtIGJhbV9jaGFubmVsX2RpciB7DQo+ICsJQkFN X1BJUEVfQ09OU1VNRVIgPSAwLAkvKiBjaGFubmVsIHJlYWRzIGZyb20gZGF0YS1maWZvIG9yIG1l bW9yeSAqLw0KPiArCUJBTV9QSVBFX1BST0RVQ0VSLAkvKiBjaGFubmVsIHdyaXRlcyB0byBkYXRh LWZpZm8gb3IgbWVtb3J5ICovDQo+ICt9Ow0KPiArDQo+ICtzdHJ1Y3QgYmFtX2Rlc2NfaHcgew0K PiArCXUzMiBhZGRyOwkJLyogQnVmZmVyIHBoeXNpY2FsIGFkZHJlc3MgKi8NCj4gKwl1MTYgc2l6 ZTsJCS8qIEJ1ZmZlciBzaXplIGluIGJ5dGVzICovDQo+ICsJdTE2IGZsYWdzOw0KPiArfSBfX3Bh Y2tlZDsNCj4gKw0KPiArI2RlZmluZSBERVNDX0ZMQUdfSU5UCUJJVCgxNSkNCj4gKyNkZWZpbmUg REVTQ19GTEFHX0VPVAlCSVQoMTQpDQo+ICsjZGVmaW5lIERFU0NfRkxBR19FT0IJQklUKDEzKQ0K PiArDQo+ICtzdHJ1Y3QgYmFtX2FzeW5jX2Rlc2Mgew0KPiArCXN0cnVjdCB2aXJ0X2RtYV9kZXNj IHZkOw0KPiArDQo+ICsJdTMyIG51bV9kZXNjOw0KPiArCXUzMiB4ZmVyX2xlbjsNCj4gKwlzdHJ1 Y3QgYmFtX2Rlc2NfaHcgKmN1cnJfZGVzYzsNCj4gKw0KPiArCWVudW0gYmFtX2NoYW5uZWxfZGly IGRpcjsNCj4gKwlzaXplX3QgbGVuZ3RoOw0KPiArCXN0cnVjdCBiYW1fZGVzY19odyBkZXNjWzBd Ow0KPiArfTsNCj4gKw0KPiArI2RlZmluZSBCQU1fQ1RSTAkJCTB4MDAwMA0KPiArI2RlZmluZSBC QU1fUkVWSVNJT04JCQkweDAwMDQNCj4gKyNkZWZpbmUgQkFNX1NXX1JFVklTSU9OCQkJMHgwMDgw DQo+ICsjZGVmaW5lIEJBTV9OVU1fUElQRVMJCQkweDAwM0MNCj4gKyNkZWZpbmUgQkFNX1RJTUVS CQkJMHgwMDQwDQo+ICsjZGVmaW5lIEJBTV9USU1FUl9DVFJMCQkJMHgwMDQ0DQo+ICsjZGVmaW5l IEJBTV9ERVNDX0NOVF9UUlNITEQJCTB4MDAwOA0KPiArI2RlZmluZSBCQU1fSVJRX1NSQ1MJCQkw eDAwMEMNCj4gKyNkZWZpbmUgQkFNX0lSUV9TUkNTX01TSwkJMHgwMDEwDQo+ICsjZGVmaW5lIEJB TV9JUlFfU1JDU19VTk1BU0tFRAkJMHgwMDMwDQo+ICsjZGVmaW5lIEJBTV9JUlFfU1RUUwkJCTB4 MDAxNA0KPiArI2RlZmluZSBCQU1fSVJRX0NMUgkJCTB4MDAxOA0KPiArI2RlZmluZSBCQU1fSVJR X0VOCQkJMHgwMDFDDQo+ICsjZGVmaW5lIEJBTV9DTkZHX0JJVFMJCQkweDAwN0MNCj4gKyNkZWZp bmUgQkFNX0lSUV9TUkNTX0VFKHBpcGUpCQkoMHgwODAwICsgKChwaXBlKSAqIDB4ODApKQ0KPiAr I2RlZmluZSBCQU1fSVJRX1NSQ1NfTVNLX0VFKHBpcGUpCSgweDA4MDQgKyAoKHBpcGUpICogMHg4 MCkpDQo+ICsjZGVmaW5lIEJBTV9QX0NUUkwocGlwZSkJCSgweDEwMDAgKyAoKHBpcGUpICogMHgx MDAwKSkNCj4gKyNkZWZpbmUgQkFNX1BfUlNUKHBpcGUpCQkJKDB4MTAwNCArICgocGlwZSkgKiAw eDEwMDApKQ0KPiArI2RlZmluZSBCQU1fUF9IQUxUKHBpcGUpCQkoMHgxMDA4ICsgKChwaXBlKSAq IDB4MTAwMCkpDQo+ICsjZGVmaW5lIEJBTV9QX0lSUV9TVFRTKHBpcGUpCQkoMHgxMDEwICsgKChw aXBlKSAqIDB4MTAwMCkpDQo+ICsjZGVmaW5lIEJBTV9QX0lSUV9DTFIocGlwZSkJCSgweDEwMTQg KyAoKHBpcGUpICogMHgxMDAwKSkNCj4gKyNkZWZpbmUgQkFNX1BfSVJRX0VOKHBpcGUpCQkoMHgx MDE4ICsgKChwaXBlKSAqIDB4MTAwMCkpDQo+ICsjZGVmaW5lIEJBTV9QX0VWTlRfREVTVF9BRERS KHBpcGUpCSgweDE4MkMgKyAoKHBpcGUpICogMHgxMDAwKSkNCj4gKyNkZWZpbmUgQkFNX1BfRVZO VF9SRUcocGlwZSkJCSgweDE4MTggKyAoKHBpcGUpICogMHgxMDAwKSkNCj4gKyNkZWZpbmUgQkFN X1BfU1dfT0ZTVFMocGlwZSkJCSgweDE4MDAgKyAoKHBpcGUpICogMHgxMDAwKSkNCj4gKyNkZWZp bmUgQkFNX1BfREFUQV9GSUZPX0FERFIocGlwZSkJKDB4MTgyNCArICgocGlwZSkgKiAweDEwMDAp KQ0KPiArI2RlZmluZSBCQU1fUF9ERVNDX0ZJRk9fQUREUihwaXBlKQkoMHgxODFDICsgKChwaXBl KSAqIDB4MTAwMCkpDQo+ICsjZGVmaW5lIEJBTV9QX0VWTlRfVFJTSExEKHBpcGUpCQkoMHgxODI4 ICsgKChwaXBlKSAqIDB4MTAwMCkpDQo+ICsjZGVmaW5lIEJBTV9QX0ZJRk9fU0laRVMocGlwZSkJ CSgweDE4MjAgKyAoKHBpcGUpICogMHgxMDAwKSkNCj4gKw0KPiArLyogQkFNIENUUkwgKi8NCj4g KyNkZWZpbmUgQkFNX1NXX1JTVAkJCUJJVCgwKQ0KPiArI2RlZmluZSBCQU1fRU4JCQkJQklUKDEp DQo+ICsjZGVmaW5lIEJBTV9FTl9BQ0NVTQkJCUJJVCg0KQ0KPiArI2RlZmluZSBCQU1fVEVTVEJV U19TRUxfU0hJRlQJCTUNCj4gKyNkZWZpbmUgQkFNX1RFU1RCVVNfU0VMX01BU0sJCTB4M0YNCj4g KyNkZWZpbmUgQkFNX0RFU0NfQ0FDSEVfU0VMX1NISUZUCTEzDQo+ICsjZGVmaW5lIEJBTV9ERVND X0NBQ0hFX1NFTF9NQVNLCQkweDMNCj4gKyNkZWZpbmUgQkFNX0NBQ0hFRF9ERVNDX1NUT1JFCQlC SVQoMTUpDQo+ICsjZGVmaW5lIElCQ19ESVNBQkxFCQkJQklUKDE2KQ0KPiArDQo+ICsvKiBCQU0g UkVWSVNJT04gKi8NCj4gKyNkZWZpbmUgUkVWSVNJT05fU0hJRlQJCTANCj4gKyNkZWZpbmUgUkVW SVNJT05fTUFTSwkJMHhGRg0KPiArI2RlZmluZSBOVU1fRUVTX1NISUZUCQk4DQo+ICsjZGVmaW5l IE5VTV9FRVNfTUFTSwkJMHhGDQo+ICsjZGVmaW5lIENFX0JVRkZFUl9TSVpFCQlCSVQoMTMpDQo+ ICsjZGVmaW5lIEFYSV9BQ1RJVkUJCUJJVCgxNCkNCj4gKyNkZWZpbmUgVVNFX1ZNSURNVAkJQklU KDE1KQ0KPiArI2RlZmluZSBTRUNVUkVECQkJQklUKDE2KQ0KPiArI2RlZmluZSBCQU1fSEFTX05P X0JZUEFTUwlCSVQoMTcpDQo+ICsjZGVmaW5lIEhJR0hfRlJFUVVFTkNZX0JBTQlCSVQoMTgpDQo+ ICsjZGVmaW5lIElOQUNUSVZfVE1SU19FWFNUCUJJVCgxOSkNCj4gKyNkZWZpbmUgTlVNX0lOQUNU SVZfVE1SUwlCSVQoMjApDQo+ICsjZGVmaW5lIERFU0NfQ0FDSEVfREVQVEhfU0hJRlQJMjENCj4g KyNkZWZpbmUgREVTQ19DQUNIRV9ERVBUSF8xCSgwIDw8IERFU0NfQ0FDSEVfREVQVEhfU0hJRlQp DQo+ICsjZGVmaW5lIERFU0NfQ0FDSEVfREVQVEhfMgkoMSA8PCBERVNDX0NBQ0hFX0RFUFRIX1NI SUZUKQ0KPiArI2RlZmluZSBERVNDX0NBQ0hFX0RFUFRIXzMJKDIgPDwgREVTQ19DQUNIRV9ERVBU SF9TSElGVCkNCj4gKyNkZWZpbmUgREVTQ19DQUNIRV9ERVBUSF80CSgzIDw8IERFU0NfQ0FDSEVf REVQVEhfU0hJRlQpDQo+ICsjZGVmaW5lIENNRF9ERVNDX0VOCQlCSVQoMjMpDQo+ICsjZGVmaW5l IElOQUNUSVZfVE1SX0JBU0VfU0hJRlQJMjQNCj4gKyNkZWZpbmUgSU5BQ1RJVl9UTVJfQkFTRV9N QVNLCTB4RkYNCj4gKw0KPiArLyogQkFNIE5VTSBQSVBFUyAqLw0KPiArI2RlZmluZSBCQU1fTlVN X1BJUEVTX1NISUZUCQkwDQo+ICsjZGVmaW5lIEJBTV9OVU1fUElQRVNfTUFTSwkJMHhGRg0KPiAr I2RlZmluZSBQRVJJUEhfTk9OX1BJUEVfR1JQX1NISUZUCTE2DQo+ICsjZGVmaW5lIFBFUklQSF9O T05fUElQX0dSUF9NQVNLCQkweEZGDQo+ICsjZGVmaW5lIEJBTV9OT05fUElQRV9HUlBfU0hJRlQJ CTI0DQo+ICsjZGVmaW5lIEJBTV9OT05fUElQRV9HUlBfTUFTSwkJMHhGRg0KPiArDQo+ICsvKiBC QU0gQ05GRyBCSVRTICovDQo+ICsjZGVmaW5lIEJBTV9QSVBFX0NORkcJCUJJVCgyKQ0KPiArI2Rl ZmluZSBCQU1fRlVMTF9QSVBFCQlCSVQoMTEpDQo+ICsjZGVmaW5lIEJBTV9OT19FWFRfUF9SU1QJ QklUKDEyKQ0KPiArI2RlZmluZSBCQU1fSUJDX0RJU0FCTEUJCUJJVCgxMykNCj4gKyNkZWZpbmUg QkFNX1NCX0NMS19SRVEJCUJJVCgxNCkNCj4gKyNkZWZpbmUgQkFNX1BTTV9DU1dfUkVRCQlCSVQo MTUpDQo+ICsjZGVmaW5lIEJBTV9QU01fUF9SRVMJCUJJVCgxNikNCj4gKyNkZWZpbmUgQkFNX0FV X1BfUkVTCQlCSVQoMTcpDQo+ICsjZGVmaW5lIEJBTV9TSV9QX1JFUwkJQklUKDE4KQ0KPiArI2Rl ZmluZSBCQU1fV0JfUF9SRVMJCUJJVCgxOSkNCj4gKyNkZWZpbmUgQkFNX1dCX0JMS19DU1cJCUJJ VCgyMCkNCj4gKyNkZWZpbmUgQkFNX1dCX0NTV19BQ0tfSURMCUJJVCgyMSkNCj4gKyNkZWZpbmUg QkFNX1dCX1JFVFJfU1ZQTlQJQklUKDIyKQ0KPiArI2RlZmluZSBCQU1fV0JfRFNDX0FWTF9QX1JT VAlCSVQoMjMpDQo+ICsjZGVmaW5lIEJBTV9SRUdfUF9FTgkJQklUKDI0KQ0KPiArI2RlZmluZSBC QU1fUFNNX1BfSERfREFUQQlCSVQoMjUpDQo+ICsjZGVmaW5lIEJBTV9BVV9BQ0NVTUVECQlCSVQo MjYpDQo+ICsjZGVmaW5lIEJBTV9DTURfRU5BQkxFCQlCSVQoMjcpDQo+ICsNCj4gKyNkZWZpbmUg QkFNX0NORkdfQklUU19ERUZBVUxUCShCQU1fUElQRV9DTkZHIHwJXA0KPiArCQkJQkFNX05PX0VY VF9QX1JTVCB8CQlcDQo+ICsJCQlCQU1fSUJDX0RJU0FCTEUgfAkJXA0KPiArCQkJQkFNX1NCX0NM S19SRVEgfAkJXA0KPiArCQkJQkFNX1BTTV9DU1dfUkVRIHwJCVwNCj4gKwkJCUJBTV9QU01fUF9S RVMgfAkJCVwNCj4gKwkJCUJBTV9BVV9QX1JFUyB8CQkJXA0KPiArCQkJQkFNX1NJX1BfUkVTIHwJ CQlcDQo+ICsJCQlCQU1fV0JfUF9SRVMgfAkJCVwNCj4gKwkJCUJBTV9XQl9CTEtfQ1NXIHwJCVwN Cj4gKwkJCUJBTV9XQl9DU1dfQUNLX0lETCB8CQlcDQo+ICsJCQlCQU1fV0JfUkVUUl9TVlBOVCB8 CQlcDQo+ICsJCQlCQU1fV0JfRFNDX0FWTF9QX1JTVCB8CQlcDQo+ICsJCQlCQU1fUkVHX1BfRU4g fAkJCVwNCj4gKwkJCUJBTV9QU01fUF9IRF9EQVRBIHwJCVwNCj4gKwkJCUJBTV9BVV9BQ0NVTUVE IHwJCVwNCj4gKwkJCUJBTV9DTURfRU5BQkxFKQ0KPiArDQo+ICsvKiBQSVBFIENUUkwgKi8NCj4g KyNkZWZpbmUJUF9FTgkJCUJJVCgxKQ0KPiArI2RlZmluZSBQX0RJUkVDVElPTgkJQklUKDMpDQo+ ICsjZGVmaW5lIFBfU1lTX1NUUk0JCUJJVCg0KQ0KPiArI2RlZmluZSBQX1NZU19NT0RFCQlCSVQo NSkNCj4gKyNkZWZpbmUgUF9BVVRPX0VPQgkJQklUKDYpDQo+ICsjZGVmaW5lIFBfQVVUT19FT0Jf U0VMX1NISUZUCTcNCj4gKyNkZWZpbmUgUF9BVVRPX0VPQl9TRUxfNTEyCSgwIDw8IFBfQVVUT19F T0JfU0VMX1NISUZUKQ0KPiArI2RlZmluZSBQX0FVVE9fRU9CX1NFTF8yNTYJKDEgPDwgUF9BVVRP X0VPQl9TRUxfU0hJRlQpDQo+ICsjZGVmaW5lIFBfQVVUT19FT0JfU0VMXzEyOAkoMiA8PCBQX0FV VE9fRU9CX1NFTF9TSElGVCkNCj4gKyNkZWZpbmUgUF9BVVRPX0VPQl9TRUxfNjQJKDMgPDwgUF9B VVRPX0VPQl9TRUxfU0hJRlQpDQo+ICsjZGVmaW5lIFBfUFJFRkVUQ0hfTElNSVRfU0hJRlQJOQ0K PiArI2RlZmluZSBQX1BSRUZFVENIX0xJTUlUXzMyCSgwIDw8IFBfUFJFRkVUQ0hfTElNSVRfU0hJ RlQpDQo+ICsjZGVmaW5lIFBfUFJFRkVUQ0hfTElNSVRfMTYJKDEgPDwgUF9QUkVGRVRDSF9MSU1J VF9TSElGVCkNCj4gKyNkZWZpbmUgUF9QUkVGRVRDSF9MSU1JVF80CSgyIDw8IFBfUFJFRkVUQ0hf TElNSVRfU0hJRlQpDQo+ICsjZGVmaW5lIFBfV1JJVEVfTldECQlCSVQoMTEpDQo+ICsjZGVmaW5l IFBfTE9DS19HUk9VUF9TSElGVAkxNg0KPiArI2RlZmluZSBQX0xPQ0tfR1JPVVBfTUFTSwkweDFG DQo+ICsNCj4gKy8qIEJBTV9ERVNDX0NOVF9UUlNITEQgKi8NCj4gKyNkZWZpbmUgQ05UX1RSU0hM RAkJMHhmZmZmDQo+ICsjZGVmaW5lIERFRkFVTFRfQ05UX1RIUlNITEQJMHg0DQo+ICsNCj4gKy8q IEJBTV9JUlFfU1JDUyAqLw0KPiArI2RlZmluZSBCQU1fSVJRCQkJQklUKDMxKQ0KPiArI2RlZmlu ZSBQX0lSUQkJCTB4N2ZmZmZmZmYNCj4gKw0KPiArLyogQkFNX0lSUV9TUkNTX01TSyAqLw0KPiAr I2RlZmluZSBCQU1fSVJRX01TSwkJQkFNX0lSUQ0KPiArI2RlZmluZSBQX0lSUV9NU0sJCVBfSVJR DQo+ICsNCj4gKy8qIEJBTV9JUlFfU1RUUyAqLw0KPiArI2RlZmluZSBCQU1fVElNRVJfSVJRCQlC SVQoNCkNCj4gKyNkZWZpbmUgQkFNX0VNUFRZX0lSUQkJQklUKDMpDQo+ICsjZGVmaW5lIEJBTV9F UlJPUl9JUlEJCUJJVCgyKQ0KPiArI2RlZmluZSBCQU1fSFJFU1BfRVJSX0lSUQlCSVQoMSkNCj4g Kw0KPiArLyogQkFNX0lSUV9DTFIgKi8NCj4gKyNkZWZpbmUgQkFNX1RJTUVSX0NMUgkJQklUKDQp DQo+ICsjZGVmaW5lIEJBTV9FTVBUWV9DTFIJCUJJVCgzKQ0KPiArI2RlZmluZSBCQU1fRVJST1Jf Q0xSCQlCSVQoMikNCj4gKyNkZWZpbmUgQkFNX0hSRVNQX0VSUl9DTFIJQklUKDEpDQo+ICsNCj4g Ky8qIEJBTV9JUlFfRU4gKi8NCj4gKyNkZWZpbmUgQkFNX1RJTUVSX0VOCQlCSVQoNCkNCj4gKyNk ZWZpbmUgQkFNX0VNUFRZX0VOCQlCSVQoMykNCj4gKyNkZWZpbmUgQkFNX0VSUk9SX0VOCQlCSVQo MikNCj4gKyNkZWZpbmUgQkFNX0hSRVNQX0VSUl9FTglCSVQoMSkNCj4gKw0KPiArLyogQkFNX1Bf SVJRX0VOICovDQo+ICsjZGVmaW5lIFBfUFJDU0RfREVTQ19FTgkJQklUKDApDQo+ICsjZGVmaW5l IFBfVElNRVJfRU4JCUJJVCgxKQ0KPiArI2RlZmluZSBQX1dBS0VfRU4JCUJJVCgyKQ0KPiArI2Rl ZmluZSBQX09VVF9PRl9ERVNDX0VOCUJJVCgzKQ0KPiArI2RlZmluZSBQX0VSUl9FTgkJQklUKDQp DQo+ICsjZGVmaW5lIFBfVFJOU0ZSX0VORF9FTgkJQklUKDUpDQo+ICsjZGVmaW5lIFBfREVGQVVM VF9JUlFTX0VOCShQX1BSQ1NEX0RFU0NfRU4gfCBQX0VSUl9FTiB8IFBfVFJOU0ZSX0VORF9FTikN Cj4gKw0KPiArLyogQkFNX1BfU1dfT0ZTVFMgKi8NCj4gKyNkZWZpbmUgUF9TV19PRlNUU19NQVNL CQkweGZmZmYNCj4gKw0KPiArI2RlZmluZSBCQU1fREVTQ19GSUZPX1NJWkUJU1pfMzJLDQo+ICsj ZGVmaW5lIE1BWF9ERVNDUklQVE9SUyAoQkFNX0RFU0NfRklGT19TSVpFIC8gc2l6ZW9mKHN0cnVj dCBiYW1fZGVzY19odykgLSAxKQ0KPiArI2RlZmluZSBCQU1fTUFYX0RBVEFfU0laRQkoU1pfMzJL IC0gOCkNCj4gKw0KPiArc3RydWN0IGJhbV9jaGFuIHsNCj4gKwlzdHJ1Y3QgdmlydF9kbWFfY2hh biB2YzsNCj4gKw0KPiArCXN0cnVjdCBiYW1fZGV2aWNlICpiZGV2Ow0KPiArDQo+ICsJLyogY29u ZmlndXJhdGlvbiBmcm9tIGRldmljZSB0cmVlICovDQo+ICsJdTMyIGlkOw0KPiArCXUzMiBlZTsN Cj4gKw0KPiArCXN0cnVjdCBiYW1fYXN5bmNfZGVzYyAqY3Vycl90eGQ7CS8qIGN1cnJlbnQgcnVu bmluZyBkbWEgKi8NCj4gKw0KPiArCS8qIHJ1bnRpbWUgY29uZmlndXJhdGlvbiAqLw0KPiArCXN0 cnVjdCBkbWFfc2xhdmVfY29uZmlnIHNsYXZlOw0KPiArDQo+ICsJLyogZmlmbyBzdG9yYWdlICov DQo+ICsJc3RydWN0IGJhbV9kZXNjX2h3ICpmaWZvX3ZpcnQ7DQo+ICsJZG1hX2FkZHJfdCBmaWZv X3BoeXM7DQo+ICsNCj4gKwkvKiBmaWZvIG1hcmtlcnMgKi8NCj4gKwl1bnNpZ25lZCBzaG9ydCBo ZWFkOwkJLyogc3RhcnQgb2YgYWN0aXZlIGRlc2NyaXB0b3IgZW50cmllcyAqLw0KPiArCXVuc2ln bmVkIHNob3J0IHRhaWw7CQkvKiBlbmQgb2YgYWN0aXZlIGRlc2NyaXB0b3IgZW50cmllcyAqLw0K PiArDQo+ICsJdW5zaWduZWQgaW50IHBhdXNlZDsJCS8qIGlzIHRoZSBjaGFubmVsIHBhdXNlZD8g Ki8NCj4gKw0KPiArCXN0cnVjdCBsaXN0X2hlYWQgbm9kZTsNCj4gK307DQo+ICsNCj4gK3N0YXRp YyBpbmxpbmUgc3RydWN0IGJhbV9jaGFuICp0b19iYW1fY2hhbihzdHJ1Y3QgZG1hX2NoYW4gKmNv bW1vbikNCj4gK3sNCj4gKwlyZXR1cm4gY29udGFpbmVyX29mKGNvbW1vbiwgc3RydWN0IGJhbV9j aGFuLCB2Yy5jaGFuKTsNCj4gK30NCj4gKw0KPiArc3RydWN0IGJhbV9kZXZpY2Ugew0KPiArCXZv aWQgX19pb21lbSAqcmVnczsNCj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXY7DQo+ICsJc3RydWN0IGRt YV9kZXZpY2UgY29tbW9uOw0KPiArCXN0cnVjdCBkZXZpY2VfZG1hX3BhcmFtZXRlcnMgZG1hX3Bh cm1zOw0KPiArCXN0cnVjdCBiYW1fY2hhbiAqY2hhbm5lbHM7DQo+ICsJdTMyIG51bV9jaGFubmVs czsNCj4gKwl1MzIgbnVtX2VlczsNCj4gKwl1bnNpZ25lZCBsb25nIGVuYWJsZWRfZWVzOw0KPiAr CWludCBpcnE7DQo+ICsJc3RydWN0IGNsayAqYmFtY2xrOw0KPiArDQo+ICsJLyogZG1hIHN0YXJ0 IHRyYW5zYWN0aW9uIHRhc2tsZXQgKi8NCj4gKwlzdHJ1Y3QgdGFza2xldF9zdHJ1Y3QgdGFzazsN Cj4gK307DQo+ICsNCj4gKyNlbmRpZiAvKiBfX1FDT01fQkFNX0RNQV9IX18gKi8NCg0KLS0gDQpB bmR5IFNoZXZjaGVua28gPGFuZHJpeS5zaGV2Y2hlbmtvQGludGVsLmNvbT4NCkludGVsIEZpbmxh bmQgT3kNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLQpJbnRlbCBGaW5sYW5kIE95ClJlZ2lzdGVyZWQgQWRkcmVzczog UEwgMjgxLCAwMDE4MSBIZWxzaW5raSAKQnVzaW5lc3MgSWRlbnRpdHkgQ29kZTogMDM1NzYwNiAt IDQgCkRvbWljaWxlZCBpbiBIZWxzaW5raSAKClRoaXMgZS1tYWlsIGFuZCBhbnkgYXR0YWNobWVu dHMgbWF5IGNvbnRhaW4gY29uZmlkZW50aWFsIG1hdGVyaWFsIGZvcgp0aGUgc29sZSB1c2Ugb2Yg dGhlIGludGVuZGVkIHJlY2lwaWVudChzKS4gQW55IHJldmlldyBvciBkaXN0cmlidXRpb24KYnkg b3RoZXJzIGlzIHN0cmljdGx5IHByb2hpYml0ZWQuIElmIHlvdSBhcmUgbm90IHRoZSBpbnRlbmRl ZApyZWNpcGllbnQsIHBsZWFzZSBjb250YWN0IHRoZSBzZW5kZXIgYW5kIGRlbGV0ZSBhbGwgY29w aWVzLgo= From mboxrd@z Thu Jan 1 00:00:00 1970 From: andriy.shevchenko@intel.com (Shevchenko, Andriy) Date: Mon, 13 Jan 2014 10:31:01 +0000 Subject: [PATCH v2 1/2] dmaengine: add Qualcomm BAM dma driver In-Reply-To: <1389380874-22753-2-git-send-email-agross@codeaurora.org> References: <1389380874-22753-1-git-send-email-agross@codeaurora.org> <1389380874-22753-2-git-send-email-agross@codeaurora.org> Message-ID: <1389609060.1871.312.camel@smile> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On Fri, 2014-01-10 at 13:07 -0600, Andy Gross wrote: > Add the DMA engine driver for the QCOM Bus Access Manager (BAM) DMA controller > found in the MSM 8x74 platforms. > > Each BAM DMA device is associated with a specific on-chip peripheral. Each > channel provides a uni-directional data transfer engine that is capable of > transferring data between the peripheral and system memory (System mode), or > between two peripherals (BAM2BAM). > > The initial release of this driver only supports slave transfers between > peripherals and system memory. > > Signed-off-by: Andy Gross > --- > drivers/dma/Kconfig | 9 + > drivers/dma/Makefile | 1 + > drivers/dma/qcom_bam_dma.c | 843 +++++++++++++++++++++++++++++++++++++++++++++ > drivers/dma/qcom_bam_dma.h | 268 ++++++++++++++ > 4 files changed, 1121 insertions(+) > create mode 100644 drivers/dma/qcom_bam_dma.c > create mode 100644 drivers/dma/qcom_bam_dma.h > > diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig > index c823daa..e58e6d2 100644 > --- a/drivers/dma/Kconfig > +++ b/drivers/dma/Kconfig > @@ -384,4 +384,13 @@ config DMATEST > config DMA_ENGINE_RAID > bool > > +config QCOM_BAM_DMA > + tristate "QCOM BAM DMA support" > + depends on ARCH_MSM || COMPILE_TEST > + select DMA_ENGINE > + select DMA_VIRTUAL_CHANNELS > + ---help--- > + Enable support for the QCOM BAM DMA controller. This controller > + provides DMA capabilities for a variety of on-chip devices. > + > endif > diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile > index 0ce2da9..7ef950a 100644 > --- a/drivers/dma/Makefile > +++ b/drivers/dma/Makefile > @@ -42,3 +42,4 @@ obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o > obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o > obj-$(CONFIG_TI_CPPI41) += cppi41.o > obj-$(CONFIG_K3_DMA) += k3dma.o > +obj-$(CONFIG_QCOM_BAM_DMA) += qcom_bam_dma.o > diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c > new file mode 100644 > index 0000000..7a84b02 > --- /dev/null > +++ b/drivers/dma/qcom_bam_dma.c > @@ -0,0 +1,843 @@ > +/* > + * QCOM BAM DMA engine driver > + * > + * Copyright (c) 2013, The Linux Foundation. All rights reserved. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 and > + * only version 2 as published by the Free Software Foundation. > + * > + * 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. > + * > + * > + * QCOM BAM DMA blocks are distributed amongst a number of the on-chip > + * peripherals on the MSM 8x74. The configuration of the channels are dependent > + * on the way they are hard wired to that specific peripheral. The peripheral > + * device tree entries specify the configuration of each channel. > + * > + * The DMA controller requires the use of external memory for storage of the > + * hardware descriptors for each channel. The descriptor FIFO is accessed as a > + * circular buffer and operations are managed according to the offset within the > + * FIFO. After pipe/channel reset, all of the pipe registers and internal state > + * are back to defaults. > + * > + * During DMA operations, we write descriptors to the FIFO, being careful to > + * handle wrapping and then write the last FIFO offset to that channel's > + * P_EVNT_REG register to kick off the transaction. The P_SW_OFSTS register > + * indicates the current FIFO offset that is being processed, so there is some > + * indication of where the hardware is currently working. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "dmaengine.h" > +#include "qcom_bam_dma.h" > + > + > +/** > + * bam_reset_channel - Reset individual BAM DMA channel > + * @bdev: bam device > + * @channel: channel id > + */ > +static void bam_reset_channel(struct bam_device *bdev, u32 channel) > +{ > + /* reset channel */ > + writel_relaxed(1, bdev->regs + BAM_P_RST(channel)); > + writel_relaxed(0, bdev->regs + BAM_P_RST(channel)); > +} > + > +/** > + * bam_alloc_chan - Allocate channel resources for DMA channel. > + * @chan: specified channel > + * > + * This function allocates the FIFO descriptor memory and resets the channel > + */ > +static int bam_alloc_chan(struct dma_chan *chan) > +{ > + struct bam_chan *bchan = to_bam_chan(chan); > + struct bam_device *bdev = bchan->bdev; > + u32 val; > + > + /* allocate FIFO descriptor space, but only if necessary */ > + if (!bchan->fifo_virt) { > + bchan->fifo_virt = dma_alloc_coherent(bdev->dev, > + BAM_DESC_FIFO_SIZE, &bchan->fifo_phys, > + GFP_KERNEL); > + > + if (!bchan->fifo_virt) { > + dev_err(bdev->dev, "Failed to allocate desc fifo\n"); > + return -ENOMEM; > + } > + } > + > + /* Go ahead and initialize the pipe/channel hardware here > + - Reset the channel to clear internal state of the FIFO > + - Program in the FIFO address > + - Configure the irq based on the EE passed in from the DT entry > + - Set mode, direction and enable channel > + > + We do this here because the channel can only be enabled once and > + can only be disabled via a reset. If done here, we don't have to > + manage additional state to figure out when to do this > + */ > + > + bam_reset_channel(bdev, bchan->id); > + > + /* write out 8 byte aligned address. We have enough space for this > + because we allocated 1 more descriptor (8 bytes) than we can use */ > + writel_relaxed(ALIGN(bchan->fifo_phys, sizeof(struct bam_desc_hw)), > + bdev->regs + BAM_P_DESC_FIFO_ADDR(bchan->id)); > + writel_relaxed(BAM_DESC_FIFO_SIZE, bdev->regs + > + BAM_P_FIFO_SIZES(bchan->id)); > + > + /* unmask and enable interrupts for defined EE, bam and error irqs */ > + writel_relaxed(BAM_IRQ_MSK, bdev->regs + BAM_IRQ_SRCS_EE(bchan->ee)); > + > + /* enable the per pipe interrupts, enable EOT, ERR, and INT irqs */ > + writel_relaxed(P_DEFAULT_IRQS_EN, bdev->regs + BAM_P_IRQ_EN(bchan->id)); > + > + /* unmask the specific pipe and EE combo */ > + val = readl_relaxed(bdev->regs + BAM_IRQ_SRCS_MSK_EE(bchan->ee)); > + val |= BIT(bchan->id); > + writel_relaxed(val, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bchan->ee)); > + > + /* set fixed direction and mode, then enable channel */ > + val = P_EN | P_SYS_MODE; > + if (bchan->slave.direction == DMA_DEV_TO_MEM) > + val |= P_DIRECTION; > + > + /* make sure the other stores occur before enabling channel */ > + wmb(); > + writel_relaxed(val, bdev->regs + BAM_P_CTRL(bchan->id)); > + > + /* do bookkeeping for tracking used EEs, used during IRQ handling */ > + set_bit(bchan->ee, &bdev->enabled_ees); > + > + bchan->head = 0; > + bchan->tail = 0; > + > + return BAM_DESC_FIFO_SIZE; > +} > + > +/** > + * bam_free_chan - Frees dma resources associated with specific channel > + * @chan: specified channel > + * > + * Free the allocated fifo descriptor memory and channel resources > + * > + */ > +static void bam_free_chan(struct dma_chan *chan) > +{ > + struct bam_chan *bchan = to_bam_chan(chan); > + struct bam_device *bdev = bchan->bdev; > + u32 val; > + > + vchan_free_chan_resources(to_virt_chan(chan)); > + > + if (bchan->curr_txd) { > + dev_err(bchan->bdev->dev, "Cannot free busy channel\n"); > + return; > + } > + > + bam_reset_channel(bdev, bchan->id); > + > + dma_free_coherent(bdev->dev, BAM_DESC_FIFO_SIZE, bchan->fifo_virt, > + bchan->fifo_phys); > + bchan->fifo_virt = NULL; > + > + /* mask irq for pipe/channel */ > + val = readl_relaxed(bdev->regs + BAM_IRQ_SRCS_MSK_EE(bchan->ee)); > + val &= ~BIT(bchan->id); > + writel_relaxed(val, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bchan->ee)); > + > + /* disable irq */ > + writel_relaxed(0, bdev->regs + BAM_P_IRQ_EN(bchan->id)); > + > + clear_bit(bchan->ee, &bdev->enabled_ees); > +} > + > +/** > + * bam_slave_config - set slave configuration for channel > + * @chan: dma channel > + * @cfg: slave configuration > + * > + * Sets slave configuration for channel > + * Only allow setting direction once. BAM channels are unidirectional > + * and the direction is set in hardware. > + * > + */ > +static void bam_slave_config(struct bam_chan *bchan, > + struct dma_slave_config *cfg) > +{ > + struct bam_device *bdev = bchan->bdev; > + u32 maxburst; > + > + if (bchan->slave.direction == DMA_DEV_TO_MEM) > + maxburst = bchan->slave.src_maxburst = cfg->src_maxburst; > + else > + maxburst = bchan->slave.dst_maxburst = cfg->dst_maxburst; > + > + /* set desc threshold */ > + writel_relaxed(maxburst, bdev->regs + BAM_DESC_CNT_TRSHLD); > +} > + > +/** > + * bam_prep_slave_sg - Prep slave sg transaction > + * > + * @chan: dma channel > + * @sgl: scatter gather list > + * @sg_len: length of sg > + * @direction: DMA transfer direction > + * @flags: DMA flags > + * @context: transfer context (unused) > + */ > +static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan, > + struct scatterlist *sgl, unsigned int sg_len, > + enum dma_transfer_direction direction, unsigned long flags, > + void *context) > +{ > + struct bam_chan *bchan = to_bam_chan(chan); > + struct bam_device *bdev = bchan->bdev; > + struct bam_async_desc *async_desc; > + struct scatterlist *sg; > + u32 i; > + struct bam_desc_hw *desc; > + > + > + if (!is_slave_direction(direction)) { > + dev_err(bdev->dev, "invalid dma direction\n"); > + return NULL; > + } > + > + /* direction has to match pipe configuration from the slave config */ > + if (direction != bchan->slave.direction) { > + dev_err(bdev->dev, > + "direction does not match configuration\n"); > + return NULL; > + } > + > + /* allocate enough room to accomodate the number of entries */ > + async_desc = kzalloc(sizeof(*async_desc) + > + (sg_len * sizeof(struct bam_desc_hw)), GFP_NOWAIT); > + > + if (!async_desc) { > + dev_err(bdev->dev, "failed to allocate async descriptor\n"); > + goto err_out; > + } > + > + async_desc->num_desc = sg_len; > + async_desc->curr_desc = async_desc->desc; > + async_desc->dir = (direction == DMA_DEV_TO_MEM) ? BAM_PIPE_PRODUCER : > + BAM_PIPE_CONSUMER; > + > + /* fill in descriptors, align hw descriptor to 8 bytes */ > + desc = async_desc->desc; > + for_each_sg(sgl, sg, sg_len, i) { > + if (sg_dma_len(sg) > BAM_MAX_DATA_SIZE) { > + dev_err(bdev->dev, "segment exceeds max size\n"); > + goto err_out; > + } > + > + desc->addr = sg_dma_address(sg); > + desc->size = sg_dma_len(sg); > + async_desc->length += sg_dma_len(sg); > + desc++; > + } > + > + return vchan_tx_prep(&bchan->vc, &async_desc->vd, flags); > + > +err_out: > + kfree(async_desc); > + return NULL; > +} > + > +/** > + * bam_dma_terminate_all - terminate all transactions > + * @chan: dma channel > + * > + * Idles channel and dequeues and frees all transactions > + * No callbacks are done > + * > +*/ > +static void bam_dma_terminate_all(struct dma_chan *chan) > +{ > + struct bam_chan *bchan = to_bam_chan(chan); > + struct bam_device *bdev = bchan->bdev; > + > + bam_reset_channel(bdev, bchan->id); > + > + vchan_free_chan_resources(&bchan->vc); > +} > + > +/** > + * bam_control - DMA device control > + * @chan: dma channel > + * @cmd: control cmd > + * @arg: cmd argument > + * > + * Perform DMA control command > + * > +*/ > +static int bam_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, > + unsigned long arg) > +{ > + struct bam_chan *bchan = to_bam_chan(chan); > + struct bam_device *bdev = bchan->bdev; > + int ret = 0; > + unsigned long flag; > + > + switch (cmd) { > + case DMA_PAUSE: > + spin_lock_irqsave(&bchan->vc.lock, flag); > + writel_relaxed(1, bdev->regs + BAM_P_HALT(bchan->id)); > + bchan->paused = 1; > + spin_unlock_irqrestore(&bchan->vc.lock, flag); > + break; > + case DMA_RESUME: > + spin_lock_irqsave(&bchan->vc.lock, flag); > + writel_relaxed(0, bdev->regs + BAM_P_HALT(bchan->id)); > + bchan->paused = 0; > + spin_unlock_irqrestore(&bchan->vc.lock, flag); > + break; > + case DMA_TERMINATE_ALL: > + spin_lock_irqsave(&bchan->vc.lock, flag); > + bam_dma_terminate_all(chan); > + spin_unlock_irqrestore(&bchan->vc.lock, flag); > + break; > + case DMA_SLAVE_CONFIG: > + bam_slave_config(bchan, (struct dma_slave_config *)arg); > + break; > + default: > + ret = -ENXIO; > + break; > + } > + > + return ret; > +} > + > +/** > + * process_irqs_per_ee - processes the interrupts for a specific ee > + * @bdev: bam controller > + * @ee: execution environment > + * > + * This function processes the interrupts for a given execution environment > + * > + */ > +static u32 process_irqs_per_ee(struct bam_device *bdev, u32 ee) > +{ > + u32 i, srcs, pipe_stts; > + unsigned long flags; > + struct bam_async_desc *async_desc; > + > + > + srcs = readl_relaxed(bdev->regs + BAM_IRQ_SRCS_EE(ee)); > + > + /* return early if no pipe/channel interrupts are present */ > + if (!(srcs & P_IRQ)) > + return srcs; > + > + for (i = 0; i < bdev->num_channels; i++) { > + struct bam_chan *bchan = &bdev->channels[i]; > + if (srcs & BIT(i)) { > + /* clear pipe irq */ > + pipe_stts = readl_relaxed(bdev->regs + > + BAM_P_IRQ_STTS(i)); > + > + writel_relaxed(pipe_stts, bdev->regs + > + BAM_P_IRQ_CLR(i)); > + > + spin_lock_irqsave(&bchan->vc.lock, flags); > + async_desc = bchan->curr_txd; > + > + if (async_desc) { > + async_desc->num_desc -= async_desc->xfer_len; > + async_desc->curr_desc += async_desc->xfer_len; > + bchan->curr_txd = NULL; > + > + /* manage FIFO */ > + bchan->head += async_desc->xfer_len; > + bchan->head %= MAX_DESCRIPTORS; > + > + /* if complete, process cookie. Otherwise > + push back to front of desc_issued so that > + it gets restarted by the tasklet */ > + if (!async_desc->num_desc) > + vchan_cookie_complete(&async_desc->vd); > + else > + list_add(&async_desc->vd.node, > + &bchan->vc.desc_issued); > + } > + > + spin_unlock_irqrestore(&bchan->vc.lock, flags); > + } > + } > + > + return srcs; > +} > + > +/** > + * bam_dma_irq - irq handler for bam controller > + * @irq: IRQ of interrupt > + * @data: callback data > + * > + * IRQ handler for the bam controller > + */ > +static irqreturn_t bam_dma_irq(int irq, void *data) > +{ > + struct bam_device *bdev = (struct bam_device *)data; > + u32 clr_mask = 0, srcs = 0; > + u32 i; > + > + > + for (i = 0; i < bdev->num_ees; i++) > + if (test_bit(i, &bdev->enabled_ees)) > + srcs |= process_irqs_per_ee(bdev, i); > + > + /* kick off tasklet to start next dma transfer */ > + if (srcs & P_IRQ) > + tasklet_schedule(&bdev->task); > + > + if (srcs & BAM_IRQ) > + clr_mask = readl_relaxed(bdev->regs + BAM_IRQ_STTS); > + > + /* don't allow reorder of the various accesses to the BAM registers */ > + mb(); > + > + writel_relaxed(clr_mask, bdev->regs + BAM_IRQ_CLR); > + > + return IRQ_HANDLED; > +} > + > +/** > + * bam_tx_status - returns status of transaction > + * @chan: dma channel > + * @cookie: transaction cookie > + * @txstate: DMA transaction state > + * > + * Return status of dma transaction > + */ > +static enum dma_status bam_tx_status(struct dma_chan *chan, dma_cookie_t cookie, > + struct dma_tx_state *txstate) > +{ > + struct bam_chan *bchan = to_bam_chan(chan); > + struct virt_dma_desc *vd; > + int ret; > + size_t residue = 0; > + unsigned int i; > + unsigned long flags; > + > + ret = dma_cookie_status(chan, cookie, txstate); > + Redundant empty line. > + if (ret == DMA_COMPLETE) > + return ret; > + > + if (!txstate) > + return bchan->paused ? DMA_PAUSED : ret; > + > + spin_lock_irqsave(&bchan->vc.lock, flags); > + vd = vchan_find_desc(&bchan->vc, cookie); > + if (vd) > + residue = container_of(vd, struct bam_async_desc, vd)->length; > + else if (bchan->curr_txd && bchan->curr_txd->vd.tx.cookie == cookie) > + for (i = 0; i < bchan->curr_txd->num_desc; i++) > + residue += bchan->curr_txd->curr_desc[i].size; > + > + dma_set_residue(txstate, residue); I'm pretty sure you could do this outside of spin lock. > + > + spin_unlock_irqrestore(&bchan->vc.lock, flags); > + > + if (ret == DMA_IN_PROGRESS && bchan->paused) > + ret = DMA_PAUSED; > + > + return ret; > +} > + > +/** > + * bam_start_dma - start next transaction > + * @bchan - bam dma channel > + * > + * Note: must hold bam dma channel vc.lock > + */ > +static void bam_start_dma(struct bam_chan *bchan) > +{ > + struct virt_dma_desc *vd = vchan_next_desc(&bchan->vc); > + struct bam_device *bdev = bchan->bdev; > + struct bam_async_desc *async_desc; > + struct bam_desc_hw *desc; > + struct bam_desc_hw *fifo = PTR_ALIGN(bchan->fifo_virt, > + sizeof(struct bam_desc_hw)); > + > + if (!vd) > + return; > + > + list_del(&vd->node); > + > + async_desc = container_of(vd, struct bam_async_desc, vd); > + bchan->curr_txd = async_desc; > + > + desc = bchan->curr_txd->curr_desc; > + > + if (async_desc->num_desc > MAX_DESCRIPTORS) > + async_desc->xfer_len = MAX_DESCRIPTORS; > + else > + async_desc->xfer_len = async_desc->num_desc; > + > + /* set INT on last descriptor */ > + desc[async_desc->xfer_len - 1].flags |= DESC_FLAG_INT; > + > + if (bchan->tail + async_desc->xfer_len > MAX_DESCRIPTORS) { > + u32 partial = MAX_DESCRIPTORS - bchan->tail; > + > + memcpy(&fifo[bchan->tail], desc, > + partial * sizeof(struct bam_desc_hw)); > + memcpy(fifo, &desc[partial], (async_desc->xfer_len - partial) * > + sizeof(struct bam_desc_hw)); I'm just curious if you could avoid memcpys at all somehow. > + } else Keep style } else { ... } Have you run checkpatch.pl? > + memcpy(&fifo[bchan->tail], desc, > + async_desc->xfer_len * sizeof(struct bam_desc_hw)); > + > + bchan->tail += async_desc->xfer_len; > + bchan->tail %= MAX_DESCRIPTORS; > + > + /* ensure descriptor writes and dma start not reordered */ > + wmb(); > + writel_relaxed(bchan->tail * sizeof(struct bam_desc_hw), > + bdev->regs + BAM_P_EVNT_REG(bchan->id)); > +} > + > +/** > + * dma_tasklet - DMA IRQ tasklet > + * @data: tasklet argument (bam controller structure) > + * > + * Sets up next DMA operation and then processes all completed transactions > + */ > +static void dma_tasklet(unsigned long data) > +{ > + struct bam_device *bdev = (struct bam_device *)data; > + struct bam_chan *bchan; > + unsigned long flags; > + unsigned int i; > + > + /* go through the channels and kick off transactions */ > + for (i = 0; i < bdev->num_channels; i++) { > + bchan = &bdev->channels[i]; > + spin_lock_irqsave(&bchan->vc.lock, flags); > + > + if (!list_empty(&bchan->vc.desc_issued) && !bchan->curr_txd) > + bam_start_dma(bchan); > + spin_unlock_irqrestore(&bchan->vc.lock, flags); > + } > +} > + > +/** > + * bam_issue_pending - starts pending transactions > + * @chan: dma channel > + * > + * Calls tasklet directly which in turn starts any pending transactions > + */ > +static void bam_issue_pending(struct dma_chan *chan) > +{ > + struct bam_chan *bchan = to_bam_chan(chan); > + unsigned long flags; > + > + spin_lock_irqsave(&bchan->vc.lock, flags); > + > + /* if work pending and idle, start a transaction */ > + if (vchan_issue_pending(&bchan->vc) && !bchan->curr_txd) > + bam_start_dma(bchan); > + > + spin_unlock_irqrestore(&bchan->vc.lock, flags); > +} > + > +/** > + * bam_dma_free_desc - free descriptor memory > + * @vd: virtual descriptor > + * > + */ > +static void bam_dma_free_desc(struct virt_dma_desc *vd) > +{ > + struct bam_async_desc *async_desc = container_of(vd, > + struct bam_async_desc, vd); > + > + kfree(async_desc); > +} > + > +struct bam_filter_args { > + struct dma_device *dev; > + u32 id; > + u32 ee; > + u32 dir; > +}; > + > +static bool bam_dma_filter(struct dma_chan *chan, void *data) > +{ > + struct bam_filter_args *args = data; > + struct bam_chan *bchan = to_bam_chan(chan); > + > + if (args->dev == chan->device && > + args->id == bchan->id) { > + > + /* we found the channel, so lets set the EE and dir */ > + bchan->ee = args->ee; > + bchan->slave.direction = args->dir ? > + DMA_DEV_TO_MEM : DMA_MEM_TO_DEV; > + return true; > + } > + > + return false; > +} > + > +static struct dma_chan *bam_dma_xlate(struct of_phandle_args *dma_spec, > + struct of_dma *of) > +{ > + struct bam_filter_args args; > + dma_cap_mask_t cap; > + > + if (dma_spec->args_count != 3) > + return NULL; > + > + args.dev = of->of_dma_data; > + args.id = dma_spec->args[0]; > + args.ee = dma_spec->args[1]; > + args.dir = dma_spec->args[2]; > + > + dma_cap_zero(cap); > + dma_cap_set(DMA_SLAVE, cap); > + > + return dma_request_channel(cap, bam_dma_filter, &args); > +} > + > +/** > + * bam_init > + * @bdev: bam device > + * > + * Initialization helper for global bam registers > + */ > +static void bam_init(struct bam_device *bdev) > +{ > + u32 val; > + > + /* read versioning information */ > + val = readl_relaxed(bdev->regs + BAM_REVISION); > + bdev->num_ees = val & NUM_EES_MASK; > + > + val = readl_relaxed(bdev->regs + BAM_NUM_PIPES); > + bdev->num_channels = val & BAM_NUM_PIPES_MASK; > + > + /* s/w reset bam */ > + /* after reset all pipes are disabled and idle */ > + val = readl_relaxed(bdev->regs + BAM_CTRL); > + val |= BAM_SW_RST; > + writel_relaxed(val, bdev->regs + BAM_CTRL); > + val &= ~BAM_SW_RST; > + writel_relaxed(val, bdev->regs + BAM_CTRL); > + > + /* make sure previous stores are visible before enabling BAM */ > + wmb(); > + > + /* enable bam */ > + val |= BAM_EN; > + writel_relaxed(val, bdev->regs + BAM_CTRL); > + > + /* set descriptor threshhold, start with 4 bytes */ > + writel_relaxed(DEFAULT_CNT_THRSHLD, bdev->regs + BAM_DESC_CNT_TRSHLD); > + > + /* Enable default set of h/w workarounds, ie all except BAM_FULL_PIPE */ > + writel_relaxed(BAM_CNFG_BITS_DEFAULT, bdev->regs + BAM_CNFG_BITS); > + > + /* enable irqs for errors */ > + writel_relaxed(BAM_ERROR_EN | BAM_HRESP_ERR_EN, > + bdev->regs + BAM_IRQ_EN); > +} > + > +static void bam_channel_init(struct bam_device *bdev, struct bam_chan *bchan, > + u32 index) > +{ > + bchan->id = index; > + bchan->bdev = bdev; > + > + vchan_init(&bchan->vc, &bdev->common); > + bchan->vc.desc_free = bam_dma_free_desc; > + > + bam_reset_channel(bdev, bchan->id); > +} > + > +static int bam_dma_probe(struct platform_device *pdev) > +{ > + struct bam_device *bdev; > + struct resource *iores, *irq_res; > + int ret, i; > + > + bdev = devm_kzalloc(&pdev->dev, sizeof(*bdev), GFP_KERNEL); > + if (!bdev) > + return -ENOMEM; > + > + bdev->dev = &pdev->dev; > + > + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + if (!iores) { > + dev_err(bdev->dev, "register resource is missing\n"); > + return -EINVAL; > + } Useless check and messaging, devm_ioremap_resource will do this for you. > + > + bdev->regs = devm_ioremap_resource(&pdev->dev, iores); > + if (IS_ERR(bdev->regs)) > + return PTR_ERR(bdev->regs); > + > + irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); > + if (!irq_res) { > + dev_err(bdev->dev, "irq resource is missing\n"); > + return -EINVAL; > + } > + > + bdev->bamclk = devm_clk_get(bdev->dev, "bam_clk"); > + if (IS_ERR(bdev->bamclk)) > + return PTR_ERR(bdev->bamclk); > + > + ret = clk_prepare_enable(bdev->bamclk); > + if (ret) { > + dev_err(bdev->dev, "failed to prepare/enable clock"); > + return ret; > + } > + > + bam_init(bdev); > + > + tasklet_init(&bdev->task, dma_tasklet, (unsigned long)bdev); > + > + bdev->channels = devm_kzalloc(bdev->dev, devm_kcalloc. > + sizeof(*bdev->channels) * bdev->num_channels, > + GFP_KERNEL); > + > + if (!bdev->channels) { > + ret = -ENOMEM; > + goto err_disable_clk; > + } > + > + /* allocate and initialize channels */ > + INIT_LIST_HEAD(&bdev->common.channels); > + > + for (i = 0; i < bdev->num_channels; i++) > + bam_channel_init(bdev, &bdev->channels[i], i); > + > + ret = devm_request_irq(bdev->dev, irq_res->start, bam_dma_irq, > + IRQF_TRIGGER_HIGH, "bam_dma", bdev); > + if (ret) { > + dev_err(bdev->dev, "cannot register IRQ\n"); > + goto err_disable_clk; > + } > + > + /* set max dma segment size */ > + bdev->common.dev = bdev->dev; > + bdev->common.dev->dma_parms = &bdev->dma_parms; > + ret = dma_set_max_seg_size(bdev->common.dev, BAM_MAX_DATA_SIZE); > + if (ret) { > + dev_err(bdev->dev, "cannot set maximum segment size\n"); > + goto err_disable_clk; > + } > + > + platform_set_drvdata(pdev, bdev); > + > + /* set capabilities */ > + dma_cap_zero(bdev->common.cap_mask); > + dma_cap_set(DMA_SLAVE, bdev->common.cap_mask); > + > + /* initialize dmaengine apis */ > + bdev->common.device_alloc_chan_resources = bam_alloc_chan; > + bdev->common.device_free_chan_resources = bam_free_chan; > + bdev->common.device_prep_slave_sg = bam_prep_slave_sg; > + bdev->common.device_control = bam_control; > + bdev->common.device_issue_pending = bam_issue_pending; > + bdev->common.device_tx_status = bam_tx_status; > + bdev->common.dev = bdev->dev; > + > + ret = dma_async_device_register(&bdev->common); > + if (ret) { > + dev_err(bdev->dev, "failed to register dma async device\n"); > + goto err_disable_clk; > + } > + > + if (pdev->dev.of_node) { > + ret = of_dma_controller_register(pdev->dev.of_node, > + bam_dma_xlate, &bdev->common); > + > + if (ret) { > + dev_err(bdev->dev, "failed to register of_dma\n"); > + goto err_unregister_dma; > + } > + } > + > + return 0; > + > +err_unregister_dma: > + dma_async_device_unregister(&bdev->common); > +err_disable_clk: > + clk_disable_unprepare(bdev->bamclk); > + return ret; > +} > + > +static int bam_dma_remove(struct platform_device *pdev) > +{ > + struct bam_device *bdev = platform_get_drvdata(pdev); > + > + dma_async_device_unregister(&bdev->common); > + > + if (pdev->dev.of_node) > + of_dma_controller_free(pdev->dev.of_node); > + > + clk_disable_unprepare(bdev->bamclk); > + > + return 0; > +} > + > +#ifdef CONFIG_OF > +static const struct of_device_id bam_of_match[] = { > + { .compatible = "qcom,bam-v1.4.0", }, > + { .compatible = "qcom,bam-v1.4.1", }, > + {} > +}; > +MODULE_DEVICE_TABLE(of, bam_of_match); > +#endif > + > +static struct platform_driver bam_dma_driver = { > + .probe = bam_dma_probe, > + .remove = bam_dma_remove, > + .driver = { > + .name = "bam-dma-engine", > + .owner = THIS_MODULE, > + .of_match_table = of_match_ptr(bam_of_match), > + }, > +}; > + > +static int __init bam_dma_init(void) > +{ > + return platform_driver_register(&bam_dma_driver); > +} > + > +static void __exit bam_dma_exit(void) > +{ > + return platform_driver_unregister(&bam_dma_driver); > +} > + > +module_init(bam_dma_init); > +module_exit(bam_dma_exit); module_platform_driver() ? > + > +MODULE_AUTHOR("Andy Gross "); > +MODULE_DESCRIPTION("QCOM BAM DMA engine driver"); > +MODULE_LICENSE("GPL v2"); > diff --git a/drivers/dma/qcom_bam_dma.h b/drivers/dma/qcom_bam_dma.h > new file mode 100644 > index 0000000..2cb3b5f > --- /dev/null > +++ b/drivers/dma/qcom_bam_dma.h > @@ -0,0 +1,268 @@ > +/* > + * Copyright (c) 2013, The Linux Foundation. All rights reserved. 2014 ? > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 and > + * only version 2 as published by the Free Software Foundation. > + * > + * 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. > + */ > +#ifndef __QCOM_BAM_DMA_H__ > +#define __QCOM_BAM_DMA_H__ > + > +#include > +#include "virt-dma.h" > + > +enum bam_channel_dir { > + BAM_PIPE_CONSUMER = 0, /* channel reads from data-fifo or memory */ > + BAM_PIPE_PRODUCER, /* channel writes to data-fifo or memory */ > +}; > + > +struct bam_desc_hw { > + u32 addr; /* Buffer physical address */ > + u16 size; /* Buffer size in bytes */ > + u16 flags; > +} __packed; > + > +#define DESC_FLAG_INT BIT(15) > +#define DESC_FLAG_EOT BIT(14) > +#define DESC_FLAG_EOB BIT(13) > + > +struct bam_async_desc { > + struct virt_dma_desc vd; > + > + u32 num_desc; > + u32 xfer_len; > + struct bam_desc_hw *curr_desc; > + > + enum bam_channel_dir dir; > + size_t length; > + struct bam_desc_hw desc[0]; > +}; > + > +#define BAM_CTRL 0x0000 > +#define BAM_REVISION 0x0004 > +#define BAM_SW_REVISION 0x0080 > +#define BAM_NUM_PIPES 0x003C > +#define BAM_TIMER 0x0040 > +#define BAM_TIMER_CTRL 0x0044 > +#define BAM_DESC_CNT_TRSHLD 0x0008 > +#define BAM_IRQ_SRCS 0x000C > +#define BAM_IRQ_SRCS_MSK 0x0010 > +#define BAM_IRQ_SRCS_UNMASKED 0x0030 > +#define BAM_IRQ_STTS 0x0014 > +#define BAM_IRQ_CLR 0x0018 > +#define BAM_IRQ_EN 0x001C > +#define BAM_CNFG_BITS 0x007C > +#define BAM_IRQ_SRCS_EE(pipe) (0x0800 + ((pipe) * 0x80)) > +#define BAM_IRQ_SRCS_MSK_EE(pipe) (0x0804 + ((pipe) * 0x80)) > +#define BAM_P_CTRL(pipe) (0x1000 + ((pipe) * 0x1000)) > +#define BAM_P_RST(pipe) (0x1004 + ((pipe) * 0x1000)) > +#define BAM_P_HALT(pipe) (0x1008 + ((pipe) * 0x1000)) > +#define BAM_P_IRQ_STTS(pipe) (0x1010 + ((pipe) * 0x1000)) > +#define BAM_P_IRQ_CLR(pipe) (0x1014 + ((pipe) * 0x1000)) > +#define BAM_P_IRQ_EN(pipe) (0x1018 + ((pipe) * 0x1000)) > +#define BAM_P_EVNT_DEST_ADDR(pipe) (0x182C + ((pipe) * 0x1000)) > +#define BAM_P_EVNT_REG(pipe) (0x1818 + ((pipe) * 0x1000)) > +#define BAM_P_SW_OFSTS(pipe) (0x1800 + ((pipe) * 0x1000)) > +#define BAM_P_DATA_FIFO_ADDR(pipe) (0x1824 + ((pipe) * 0x1000)) > +#define BAM_P_DESC_FIFO_ADDR(pipe) (0x181C + ((pipe) * 0x1000)) > +#define BAM_P_EVNT_TRSHLD(pipe) (0x1828 + ((pipe) * 0x1000)) > +#define BAM_P_FIFO_SIZES(pipe) (0x1820 + ((pipe) * 0x1000)) > + > +/* BAM CTRL */ > +#define BAM_SW_RST BIT(0) > +#define BAM_EN BIT(1) > +#define BAM_EN_ACCUM BIT(4) > +#define BAM_TESTBUS_SEL_SHIFT 5 > +#define BAM_TESTBUS_SEL_MASK 0x3F > +#define BAM_DESC_CACHE_SEL_SHIFT 13 > +#define BAM_DESC_CACHE_SEL_MASK 0x3 > +#define BAM_CACHED_DESC_STORE BIT(15) > +#define IBC_DISABLE BIT(16) > + > +/* BAM REVISION */ > +#define REVISION_SHIFT 0 > +#define REVISION_MASK 0xFF > +#define NUM_EES_SHIFT 8 > +#define NUM_EES_MASK 0xF > +#define CE_BUFFER_SIZE BIT(13) > +#define AXI_ACTIVE BIT(14) > +#define USE_VMIDMT BIT(15) > +#define SECURED BIT(16) > +#define BAM_HAS_NO_BYPASS BIT(17) > +#define HIGH_FREQUENCY_BAM BIT(18) > +#define INACTIV_TMRS_EXST BIT(19) > +#define NUM_INACTIV_TMRS BIT(20) > +#define DESC_CACHE_DEPTH_SHIFT 21 > +#define DESC_CACHE_DEPTH_1 (0 << DESC_CACHE_DEPTH_SHIFT) > +#define DESC_CACHE_DEPTH_2 (1 << DESC_CACHE_DEPTH_SHIFT) > +#define DESC_CACHE_DEPTH_3 (2 << DESC_CACHE_DEPTH_SHIFT) > +#define DESC_CACHE_DEPTH_4 (3 << DESC_CACHE_DEPTH_SHIFT) > +#define CMD_DESC_EN BIT(23) > +#define INACTIV_TMR_BASE_SHIFT 24 > +#define INACTIV_TMR_BASE_MASK 0xFF > + > +/* BAM NUM PIPES */ > +#define BAM_NUM_PIPES_SHIFT 0 > +#define BAM_NUM_PIPES_MASK 0xFF > +#define PERIPH_NON_PIPE_GRP_SHIFT 16 > +#define PERIPH_NON_PIP_GRP_MASK 0xFF > +#define BAM_NON_PIPE_GRP_SHIFT 24 > +#define BAM_NON_PIPE_GRP_MASK 0xFF > + > +/* BAM CNFG BITS */ > +#define BAM_PIPE_CNFG BIT(2) > +#define BAM_FULL_PIPE BIT(11) > +#define BAM_NO_EXT_P_RST BIT(12) > +#define BAM_IBC_DISABLE BIT(13) > +#define BAM_SB_CLK_REQ BIT(14) > +#define BAM_PSM_CSW_REQ BIT(15) > +#define BAM_PSM_P_RES BIT(16) > +#define BAM_AU_P_RES BIT(17) > +#define BAM_SI_P_RES BIT(18) > +#define BAM_WB_P_RES BIT(19) > +#define BAM_WB_BLK_CSW BIT(20) > +#define BAM_WB_CSW_ACK_IDL BIT(21) > +#define BAM_WB_RETR_SVPNT BIT(22) > +#define BAM_WB_DSC_AVL_P_RST BIT(23) > +#define BAM_REG_P_EN BIT(24) > +#define BAM_PSM_P_HD_DATA BIT(25) > +#define BAM_AU_ACCUMED BIT(26) > +#define BAM_CMD_ENABLE BIT(27) > + > +#define BAM_CNFG_BITS_DEFAULT (BAM_PIPE_CNFG | \ > + BAM_NO_EXT_P_RST | \ > + BAM_IBC_DISABLE | \ > + BAM_SB_CLK_REQ | \ > + BAM_PSM_CSW_REQ | \ > + BAM_PSM_P_RES | \ > + BAM_AU_P_RES | \ > + BAM_SI_P_RES | \ > + BAM_WB_P_RES | \ > + BAM_WB_BLK_CSW | \ > + BAM_WB_CSW_ACK_IDL | \ > + BAM_WB_RETR_SVPNT | \ > + BAM_WB_DSC_AVL_P_RST | \ > + BAM_REG_P_EN | \ > + BAM_PSM_P_HD_DATA | \ > + BAM_AU_ACCUMED | \ > + BAM_CMD_ENABLE) > + > +/* PIPE CTRL */ > +#define P_EN BIT(1) > +#define P_DIRECTION BIT(3) > +#define P_SYS_STRM BIT(4) > +#define P_SYS_MODE BIT(5) > +#define P_AUTO_EOB BIT(6) > +#define P_AUTO_EOB_SEL_SHIFT 7 > +#define P_AUTO_EOB_SEL_512 (0 << P_AUTO_EOB_SEL_SHIFT) > +#define P_AUTO_EOB_SEL_256 (1 << P_AUTO_EOB_SEL_SHIFT) > +#define P_AUTO_EOB_SEL_128 (2 << P_AUTO_EOB_SEL_SHIFT) > +#define P_AUTO_EOB_SEL_64 (3 << P_AUTO_EOB_SEL_SHIFT) > +#define P_PREFETCH_LIMIT_SHIFT 9 > +#define P_PREFETCH_LIMIT_32 (0 << P_PREFETCH_LIMIT_SHIFT) > +#define P_PREFETCH_LIMIT_16 (1 << P_PREFETCH_LIMIT_SHIFT) > +#define P_PREFETCH_LIMIT_4 (2 << P_PREFETCH_LIMIT_SHIFT) > +#define P_WRITE_NWD BIT(11) > +#define P_LOCK_GROUP_SHIFT 16 > +#define P_LOCK_GROUP_MASK 0x1F > + > +/* BAM_DESC_CNT_TRSHLD */ > +#define CNT_TRSHLD 0xffff > +#define DEFAULT_CNT_THRSHLD 0x4 > + > +/* BAM_IRQ_SRCS */ > +#define BAM_IRQ BIT(31) > +#define P_IRQ 0x7fffffff > + > +/* BAM_IRQ_SRCS_MSK */ > +#define BAM_IRQ_MSK BAM_IRQ > +#define P_IRQ_MSK P_IRQ > + > +/* BAM_IRQ_STTS */ > +#define BAM_TIMER_IRQ BIT(4) > +#define BAM_EMPTY_IRQ BIT(3) > +#define BAM_ERROR_IRQ BIT(2) > +#define BAM_HRESP_ERR_IRQ BIT(1) > + > +/* BAM_IRQ_CLR */ > +#define BAM_TIMER_CLR BIT(4) > +#define BAM_EMPTY_CLR BIT(3) > +#define BAM_ERROR_CLR BIT(2) > +#define BAM_HRESP_ERR_CLR BIT(1) > + > +/* BAM_IRQ_EN */ > +#define BAM_TIMER_EN BIT(4) > +#define BAM_EMPTY_EN BIT(3) > +#define BAM_ERROR_EN BIT(2) > +#define BAM_HRESP_ERR_EN BIT(1) > + > +/* BAM_P_IRQ_EN */ > +#define P_PRCSD_DESC_EN BIT(0) > +#define P_TIMER_EN BIT(1) > +#define P_WAKE_EN BIT(2) > +#define P_OUT_OF_DESC_EN BIT(3) > +#define P_ERR_EN BIT(4) > +#define P_TRNSFR_END_EN BIT(5) > +#define P_DEFAULT_IRQS_EN (P_PRCSD_DESC_EN | P_ERR_EN | P_TRNSFR_END_EN) > + > +/* BAM_P_SW_OFSTS */ > +#define P_SW_OFSTS_MASK 0xffff > + > +#define BAM_DESC_FIFO_SIZE SZ_32K > +#define MAX_DESCRIPTORS (BAM_DESC_FIFO_SIZE / sizeof(struct bam_desc_hw) - 1) > +#define BAM_MAX_DATA_SIZE (SZ_32K - 8) > + > +struct bam_chan { > + struct virt_dma_chan vc; > + > + struct bam_device *bdev; > + > + /* configuration from device tree */ > + u32 id; > + u32 ee; > + > + struct bam_async_desc *curr_txd; /* current running dma */ > + > + /* runtime configuration */ > + struct dma_slave_config slave; > + > + /* fifo storage */ > + struct bam_desc_hw *fifo_virt; > + dma_addr_t fifo_phys; > + > + /* fifo markers */ > + unsigned short head; /* start of active descriptor entries */ > + unsigned short tail; /* end of active descriptor entries */ > + > + unsigned int paused; /* is the channel paused? */ > + > + struct list_head node; > +}; > + > +static inline struct bam_chan *to_bam_chan(struct dma_chan *common) > +{ > + return container_of(common, struct bam_chan, vc.chan); > +} > + > +struct bam_device { > + void __iomem *regs; > + struct device *dev; > + struct dma_device common; > + struct device_dma_parameters dma_parms; > + struct bam_chan *channels; > + u32 num_channels; > + u32 num_ees; > + unsigned long enabled_ees; > + int irq; > + struct clk *bamclk; > + > + /* dma start transaction tasklet */ > + struct tasklet_struct task; > +}; > + > +#endif /* __QCOM_BAM_DMA_H__ */ -- Andy Shevchenko Intel Finland Oy --------------------------------------------------------------------- Intel Finland Oy Registered Address: PL 281, 00181 Helsinki Business Identity Code: 0357606 - 4 Domiciled in Helsinki This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.