From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: [V3,2/2] dmaengine: fsl-dpaa2-qdma: Add NXP dpaa2 qDMA controller driver for Layerscape SoCs From: Peng Ma Message-Id: <20190409072212.15860-2-peng.ma@nxp.com> Date: Tue, 9 Apr 2019 15:22:12 +0800 To: vkoul@kernel.org, dan.j.williams@intel.com, leoyang.li@nxp.com Cc: linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org, Peng Ma List-ID: RFBQQTIoRGF0YSBQYXRoIEFjY2VsZXJhdGlvbiBBcmNoaXRlY3R1cmUgMikgcURNQQpUaGUgcURN QSBzdXBwb3J0cyBjaGFubmVsIHZpcnR1YWxpemF0aW9uIGJ5IGFsbG93aW5nIERNQSBqb2JzIHRv IGJlIGVucXVldWVkCmludG8gZGlmZmVyZW50IGZyYW1lIHF1ZXVlcy4gQ29yZSBjYW4gaW5pdGlh dGUgYSBETUEgdHJhbnNhY3Rpb24gYnkgcHJlcGFyaW5nCmEgZnJhbWUgZGVzY3JpcHRvcihGRCkg Zm9yIGVhY2ggRE1BIGpvYiBhbmQgZW5xdWV1aW5nIHRoaXMgam9iIHRvIGEgZnJhbWUgcXVldWUu CnRocm91Z2ggYSBoYXJkd2FyZSBwb3J0YWwuIFRoZSBxRE1BIHByZWZldGNoZXMgRE1BIGpvYnMg ZnJvbSB0aGUgZnJhbWUgcXVldWVzLgpJdCB0aGVuIHNjaGVkdWxlcyBhbmQgZGlzcGF0Y2hlcyB0 byBpbnRlcm5hbCBETUEgaGFyZHdhcmUgZW5naW5lcywgd2hpY2gKZ2VuZXJhdGUgcmVhZCBhbmQg d3JpdGUgcmVxdWVzdHMuIEJvdGggcURNQSBzb3VyY2UgZGF0YSBhbmQgZGVzdGluYXRpb24gZGF0 YSBjYW4KYmUgZWl0aGVyIGNvbnRpZ3VvdXMgb3Igbm9uLWNvbnRpZ3VvdXMgdXNpbmcgb25lIG9y IG1vcmUgc2NhdHRlci9nYXRoZXIgdGFibGVzLgpUaGUgcURNQSBzdXBwb3J0cyBnbG9iYWwgYmFu ZHdpZHRoIGZsb3cgY29udHJvbCB3aGVyZSBhbGwgRE1BIHRyYW5zYWN0aW9ucyBhcmUKc3RhbGxl ZCBpZiB0aGUgYmFuZHdpZHRoIHRocmVzaG9sZCBoYXMgYmVlbiByZWFjaGVkLiBBbHNvIHN1cHBv cnRlZCBhcmUKdHJhbnNhY3Rpb24gYmFzZWQgcmVhZCB0aHJvdHRsaW5nLgoKQWRkIE5YUCBkcHBh MiBxRE1BIHRvIHN1cHBvcnQgc29tZSBvZiBMYXllcnNjYXBlIFNvQ3MuCnN1Y2ggYXM6IExTMTA4 OEEsIExTMjA4eEEsIExYMiwgZXRjLgoKU2lnbmVkLW9mZi1ieTogUGVuZyBNYSA8cGVuZy5tYUBu eHAuY29tPgotLS0KY2hhbmdlZCBmb3IgdjM6CgktIEFkZCBkZXBlbmRzIG9uIGFybTY0IGZvciBk cGFhMiBxZG1hIGRyaXZlciAKCS0gVGhlIGRwYWEyX2lvX3NlcnZpY2VfW2RlXXJlZ2lzdGVyIGZ1 bmN0aW9ucyBoYXZlIGEgbmV3IHBhcmFtZXRlcgoJU28gdXBkYXRlIGFsbCBjYWxscyB0byBzb21l IGZ1bmN0aW9ucwoKIGRyaXZlcnMvZG1hL0tjb25maWcgICAgICAgICAgICAgICAgICAgICB8ICAg IDIgKwogZHJpdmVycy9kbWEvTWFrZWZpbGUgICAgICAgICAgICAgICAgICAgIHwgICAgMSArCiBk cml2ZXJzL2RtYS9mc2wtZHBhYTItcWRtYS9LY29uZmlnICAgICAgfCAgICA5ICsKIGRyaXZlcnMv ZG1hL2ZzbC1kcGFhMi1xZG1hL01ha2VmaWxlICAgICB8ICAgIDMgKwogZHJpdmVycy9kbWEvZnNs LWRwYWEyLXFkbWEvZHBhYTItcWRtYS5jIHwgIDc4MiArKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrCiBkcml2ZXJzL2RtYS9mc2wtZHBhYTItcWRtYS9kcGFhMi1xZG1hLmggfCAgMTUyICsr KysrKwogNiBmaWxlcyBjaGFuZ2VkLCA5NDkgaW5zZXJ0aW9ucygrKSwgMCBkZWxldGlvbnMoLSkK IGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2RtYS9mc2wtZHBhYTItcWRtYS9LY29uZmlnCiBj cmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9kbWEvZnNsLWRwYWEyLXFkbWEvTWFrZWZpbGUKIGNy ZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2RtYS9mc2wtZHBhYTItcWRtYS9kcGFhMi1xZG1hLmMK IGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2RtYS9mc2wtZHBhYTItcWRtYS9kcGFhMi1xZG1h LmgKCmRpZmYgLS1naXQgYS9kcml2ZXJzL2RtYS9LY29uZmlnIGIvZHJpdmVycy9kbWEvS2NvbmZp ZwppbmRleCBlYWY3OGY0Li4wOGFhZTAxIDEwMDY0NAotLS0gYS9kcml2ZXJzL2RtYS9LY29uZmln CisrKyBiL2RyaXZlcnMvZG1hL0tjb25maWcKQEAgLTY3MSw2ICs2NzEsOCBAQCBzb3VyY2UgImRy aXZlcnMvZG1hL3NoL0tjb25maWciCiAKIHNvdXJjZSAiZHJpdmVycy9kbWEvdGkvS2NvbmZpZyIK IAorc291cmNlICJkcml2ZXJzL2RtYS9mc2wtZHBhYTItcWRtYS9LY29uZmlnIgorCiAjIGNsaWVu dHMKIGNvbW1lbnQgIkRNQSBDbGllbnRzIgogCWRlcGVuZHMgb24gRE1BX0VOR0lORQpkaWZmIC0t Z2l0IGEvZHJpdmVycy9kbWEvTWFrZWZpbGUgYi9kcml2ZXJzL2RtYS9NYWtlZmlsZQppbmRleCA2 MTI2ZTFjLi4yNDk5ZWQ4IDEwMDY0NAotLS0gYS9kcml2ZXJzL2RtYS9NYWtlZmlsZQorKysgYi9k cml2ZXJzL2RtYS9NYWtlZmlsZQpAQCAtNzUsNiArNzUsNyBAQCBvYmotJChDT05GSUdfVU5JUEhJ RVJfTURNQUMpICs9IHVuaXBoaWVyLW1kbWFjLm8KIG9iai0kKENPTkZJR19YR0VORV9ETUEpICs9 IHhnZW5lLWRtYS5vCiBvYmotJChDT05GSUdfWlhfRE1BKSArPSB6eF9kbWEubwogb2JqLSQoQ09O RklHX1NUX0ZETUEpICs9IHN0X2ZkbWEubworb2JqLSQoQ09ORklHX0ZTTF9EUEFBMl9RRE1BKSAr PSBmc2wtZHBhYTItcWRtYS8KIAogb2JqLXkgKz0gbWVkaWF0ZWsvCiBvYmoteSArPSBxY29tLwpk aWZmIC0tZ2l0IGEvZHJpdmVycy9kbWEvZnNsLWRwYWEyLXFkbWEvS2NvbmZpZyBiL2RyaXZlcnMv ZG1hL2ZzbC1kcGFhMi1xZG1hL0tjb25maWcKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAw MDAwMC4uMjU4ZWQ2YgotLS0gL2Rldi9udWxsCisrKyBiL2RyaXZlcnMvZG1hL2ZzbC1kcGFhMi1x ZG1hL0tjb25maWcKQEAgLTAsMCArMSw5IEBACittZW51Y29uZmlnIEZTTF9EUEFBMl9RRE1BCisJ dHJpc3RhdGUgIk5YUCBEUEFBMiBRRE1BIgorCWRlcGVuZHMgb24gQVJNNjQKKwlkZXBlbmRzIG9u IEZTTF9NQ19CVVMgJiYgRlNMX01DX0RQSU8KKwlzZWxlY3QgRE1BX0VOR0lORQorCXNlbGVjdCBE TUFfVklSVFVBTF9DSEFOTkVMUworCWhlbHAKKwkgIE5YUCBEYXRhIFBhdGggQWNjZWxlcmF0aW9u IEFyY2hpdGVjdHVyZSAyIFFETUEgZHJpdmVyLAorCSAgdXNpbmcgdGhlIE5YUCBNQyBidXMgZHJp dmVyLgpkaWZmIC0tZ2l0IGEvZHJpdmVycy9kbWEvZnNsLWRwYWEyLXFkbWEvTWFrZWZpbGUgYi9k cml2ZXJzL2RtYS9mc2wtZHBhYTItcWRtYS9NYWtlZmlsZQpuZXcgZmlsZSBtb2RlIDEwMDY0NApp bmRleCAwMDAwMDAwLi5jMWQwMjI2Ci0tLSAvZGV2L251bGwKKysrIGIvZHJpdmVycy9kbWEvZnNs LWRwYWEyLXFkbWEvTWFrZWZpbGUKQEAgLTAsMCArMSwzIEBACisjIFNQRFgtTGljZW5zZS1JZGVu dGlmaWVyOiBHUEwtMi4wCisjIE1ha2VmaWxlIGZvciB0aGUgTlhQIERQQUEyIHFETUEgY29udHJv bGxlcnMKK29iai0kKENPTkZJR19GU0xfRFBBQTJfUURNQSkgKz0gZHBhYTItcWRtYS5vIGRwZG1h aS5vCmRpZmYgLS1naXQgYS9kcml2ZXJzL2RtYS9mc2wtZHBhYTItcWRtYS9kcGFhMi1xZG1hLmMg Yi9kcml2ZXJzL2RtYS9mc2wtZHBhYTItcWRtYS9kcGFhMi1xZG1hLmMKbmV3IGZpbGUgbW9kZSAx MDA2NDQKaW5kZXggMDAwMDAwMC4uMGNkZGUwZgotLS0gL2Rldi9udWxsCisrKyBiL2RyaXZlcnMv ZG1hL2ZzbC1kcGFhMi1xZG1hL2RwYWEyLXFkbWEuYwpAQCAtMCwwICsxLDc4MiBAQAorLy8gU1BE WC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAKKy8vIENvcHlyaWdodCAyMDE0LTIwMTggTlhQ CisKKy8qCisgKiBBdXRob3I6IENoYW5nbWluZyBIdWFuZyA8amVycnkuaHVhbmdAbnhwLmNvbT4K KyAqCisgKiBEcml2ZXIgZm9yIHRoZSBOWFAgUURNQSBlbmdpbmUgd2l0aCBRTWFuIG1vZGUuCisg KiBDaGFubmVsIHZpcnR1YWxpemF0aW9uIGlzIHN1cHBvcnRlZCB0aHJvdWdoIGVucXVldWluZyBv ZiBETUEgam9icyB0bywKKyAqIG9yIGRlcXVldWluZyBETUEgam9icyBmcm9tIGRpZmZlcmVudCB3 b3JrIHF1ZXVlcyB3aXRoIFFNYW4gcG9ydGFsLgorICogVGhpcyBtb2R1bGUgY2FuIGJlIGZvdW5k IG9uIE5YUCBMUzIgU29Dcy4KKyAqCisgKi8KKworI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KKyNp bmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KKyNpbmNsdWRlIDxsaW51eC9kbWFwb29sLmg+CisjaW5j bHVkZSA8bGludXgvb2ZfaXJxLmg+CisjaW5jbHVkZSA8bGludXgvaW9tbXUuaD4KKyNpbmNsdWRl IDxsaW51eC9zeXNfc29jLmg+CisjaW5jbHVkZSA8bGludXgvZnNsL21jLmg+CisjaW5jbHVkZSA8 c29jL2ZzbC9kcGFhMi1pby5oPgorCisjaW5jbHVkZSAiLi4vdmlydC1kbWEuaCIKKyNpbmNsdWRl ICJkcGRtYWlfY21kLmgiCisjaW5jbHVkZSAiZHBkbWFpLmgiCisjaW5jbHVkZSAiZHBhYTItcWRt YS5oIgorCitzdGF0aWMgYm9vbCBzbW11X2Rpc2FibGUgPSB0cnVlOworCitzdGF0aWMgc3RydWN0 IGRwYWEyX3FkbWFfY2hhbiAqdG9fZHBhYTJfcWRtYV9jaGFuKHN0cnVjdCBkbWFfY2hhbiAqY2hh bikKK3sKKwlyZXR1cm4gY29udGFpbmVyX29mKGNoYW4sIHN0cnVjdCBkcGFhMl9xZG1hX2NoYW4s IHZjaGFuLmNoYW4pOworfQorCitzdGF0aWMgc3RydWN0IGRwYWEyX3FkbWFfY29tcCAqdG9fZnNs X3FkbWFfY29tcChzdHJ1Y3QgdmlydF9kbWFfZGVzYyAqdmQpCit7CisJcmV0dXJuIGNvbnRhaW5l cl9vZih2ZCwgc3RydWN0IGRwYWEyX3FkbWFfY29tcCwgdmRlc2MpOworfQorCitzdGF0aWMgaW50 IGRwYWEyX3FkbWFfYWxsb2NfY2hhbl9yZXNvdXJjZXMoc3RydWN0IGRtYV9jaGFuICpjaGFuKQor eworCXN0cnVjdCBkcGFhMl9xZG1hX2NoYW4gKmRwYWEyX2NoYW4gPSB0b19kcGFhMl9xZG1hX2No YW4oY2hhbik7CisJc3RydWN0IGRwYWEyX3FkbWFfZW5naW5lICpkcGFhMl9xZG1hID0gZHBhYTJf Y2hhbi0+cWRtYTsKKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmZHBhYTJfcWRtYS0+cHJpdi0+ZHBk bWFpX2Rldi0+ZGV2OworCisJZHBhYTJfY2hhbi0+ZmRfcG9vbCA9IGRtYV9wb29sX2NyZWF0ZSgi ZmRfcG9vbCIsIGRldiwKKwkJCQkJICAgICAgRkRfUE9PTF9TSVpFLCAzMiwgMCk7CisJaWYgKCFk cGFhMl9jaGFuLT5mZF9wb29sKQorCQlyZXR1cm4gLUVOT01FTTsKKworCXJldHVybiBkcGFhMl9x ZG1hLT5kZXNjX2FsbG9jYXRlZCsrOworfQorCitzdGF0aWMgdm9pZCBkcGFhMl9xZG1hX2ZyZWVf Y2hhbl9yZXNvdXJjZXMoc3RydWN0IGRtYV9jaGFuICpjaGFuKQoreworCXN0cnVjdCBkcGFhMl9x ZG1hX2NoYW4gKmRwYWEyX2NoYW4gPSB0b19kcGFhMl9xZG1hX2NoYW4oY2hhbik7CisJc3RydWN0 IGRwYWEyX3FkbWFfZW5naW5lICpkcGFhMl9xZG1hID0gZHBhYTJfY2hhbi0+cWRtYTsKKwl1bnNp Z25lZCBsb25nIGZsYWdzOworCisJTElTVF9IRUFEKGhlYWQpOworCisJc3Bpbl9sb2NrX2lycXNh dmUoJmRwYWEyX2NoYW4tPnZjaGFuLmxvY2ssIGZsYWdzKTsKKwl2Y2hhbl9nZXRfYWxsX2Rlc2Ny aXB0b3JzKCZkcGFhMl9jaGFuLT52Y2hhbiwgJmhlYWQpOworCXNwaW5fdW5sb2NrX2lycXJlc3Rv cmUoJmRwYWEyX2NoYW4tPnZjaGFuLmxvY2ssIGZsYWdzKTsKKworCXZjaGFuX2RtYV9kZXNjX2Zy ZWVfbGlzdCgmZHBhYTJfY2hhbi0+dmNoYW4sICZoZWFkKTsKKworCWRwYWEyX2RwZG1haV9mcmVl X2NvbXAoZHBhYTJfY2hhbiwgJmRwYWEyX2NoYW4tPmNvbXBfdXNlZCk7CisJZHBhYTJfZHBkbWFp X2ZyZWVfY29tcChkcGFhMl9jaGFuLCAmZHBhYTJfY2hhbi0+Y29tcF9mcmVlKTsKKworCWRtYV9w b29sX2Rlc3Ryb3koZHBhYTJfY2hhbi0+ZmRfcG9vbCk7CisJZHBhYTJfcWRtYS0+ZGVzY19hbGxv Y2F0ZWQtLTsKK30KKworLyoKKyAqIFJlcXVlc3QgYSBjb21tYW5kIGRlc2NyaXB0b3IgZm9yIGVu cXVldWUuCisgKi8KK3N0YXRpYyBzdHJ1Y3QgZHBhYTJfcWRtYV9jb21wICoKK2RwYWEyX3FkbWFf cmVxdWVzdF9kZXNjKHN0cnVjdCBkcGFhMl9xZG1hX2NoYW4gKmRwYWEyX2NoYW4pCit7CisJc3Ry dWN0IGRwYWEyX3FkbWFfY29tcCAqY29tcF90ZW1wID0gTlVMTDsKKwl1bnNpZ25lZCBsb25nIGZs YWdzOworCisJc3Bpbl9sb2NrX2lycXNhdmUoJmRwYWEyX2NoYW4tPnF1ZXVlX2xvY2ssIGZsYWdz KTsKKwlpZiAobGlzdF9lbXB0eSgmZHBhYTJfY2hhbi0+Y29tcF9mcmVlKSkgeworCQlzcGluX3Vu bG9ja19pcnFyZXN0b3JlKCZkcGFhMl9jaGFuLT5xdWV1ZV9sb2NrLCBmbGFncyk7CisJCWNvbXBf dGVtcCA9IGt6YWxsb2Moc2l6ZW9mKCpjb21wX3RlbXApLCBHRlBfS0VSTkVMKTsKKwkJaWYgKCFj b21wX3RlbXApCisJCQlnb3RvIGVycjsKKwkJY29tcF90ZW1wLT5mZF92aXJ0X2FkZHIgPQorCQkJ ZG1hX3Bvb2xfYWxsb2MoZHBhYTJfY2hhbi0+ZmRfcG9vbCwgR0ZQX05PV0FJVCwKKwkJCQkgICAg ICAgJmNvbXBfdGVtcC0+ZmRfYnVzX2FkZHIpOworCQlpZiAoIWNvbXBfdGVtcC0+ZmRfdmlydF9h ZGRyKQorCQkJZ290byBlcnI7CisKKwkJY29tcF90ZW1wLT5mbF92aXJ0X2FkZHIgPQorCQkJKHZv aWQgKikoKHN0cnVjdCBkcGFhMl9mZCAqKQorCQkJCWNvbXBfdGVtcC0+ZmRfdmlydF9hZGRyICsg MSk7CisJCWNvbXBfdGVtcC0+ZmxfYnVzX2FkZHIgPSBjb21wX3RlbXAtPmZkX2J1c19hZGRyICsK KwkJCQkJc2l6ZW9mKHN0cnVjdCBkcGFhMl9mZCk7CisJCWNvbXBfdGVtcC0+ZGVzY192aXJ0X2Fk ZHIgPQorCQkJKHZvaWQgKikoKHN0cnVjdCBkcGFhMl9mbF9lbnRyeSAqKQorCQkJCWNvbXBfdGVt cC0+ZmxfdmlydF9hZGRyICsgMyk7CisJCWNvbXBfdGVtcC0+ZGVzY19idXNfYWRkciA9IGNvbXBf dGVtcC0+ZmxfYnVzX2FkZHIgKworCQkJCXNpemVvZihzdHJ1Y3QgZHBhYTJfZmxfZW50cnkpICog MzsKKworCQljb21wX3RlbXAtPnFjaGFuID0gZHBhYTJfY2hhbjsKKwkJcmV0dXJuIGNvbXBfdGVt cDsKKwl9CisJY29tcF90ZW1wID0gbGlzdF9maXJzdF9lbnRyeSgmZHBhYTJfY2hhbi0+Y29tcF9m cmVlLAorCQkJCSAgICAgc3RydWN0IGRwYWEyX3FkbWFfY29tcCwgbGlzdCk7CisJbGlzdF9kZWwo JmNvbXBfdGVtcC0+bGlzdCk7CisJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmZHBhYTJfY2hhbi0+ cXVldWVfbG9jaywgZmxhZ3MpOworCisJY29tcF90ZW1wLT5xY2hhbiA9IGRwYWEyX2NoYW47Citl cnI6CisJcmV0dXJuIGNvbXBfdGVtcDsKK30KKworc3RhdGljIHZvaWQKK2RwYWEyX3FkbWFfcG9w dWxhdGVfZmQodTMyIGZvcm1hdCwgc3RydWN0IGRwYWEyX3FkbWFfY29tcCAqZHBhYTJfY29tcCkK K3sKKwlzdHJ1Y3QgZHBhYTJfZmQgKmZkOworCisJZmQgPSAoc3RydWN0IGRwYWEyX2ZkICopZHBh YTJfY29tcC0+ZmRfdmlydF9hZGRyOworCW1lbXNldChmZCwgMCwgc2l6ZW9mKHN0cnVjdCBkcGFh Ml9mZCkpOworCisJLyogZmQgcG9wdWxhdGVkICovCisJZHBhYTJfZmRfc2V0X2FkZHIoZmQsIGRw YWEyX2NvbXAtPmZsX2J1c19hZGRyKTsKKwkvKiBCeXBhc3MgbWVtb3J5IHRyYW5zbGF0aW9uLCBG cmFtZSBsaXN0IGZvcm1hdCwgc2hvcnQgbGVuZ3RoIGRpc2FibGUgKi8KKwkvKiB3ZSBuZWVkIHRv IGRpc2FibGUgQk1UIGlmIGZzbC1tYyB1c2UgaW92YSBhZGRyICovCisJaWYgKHNtbXVfZGlzYWJs ZSkKKwkJZHBhYTJfZmRfc2V0X2JwaWQoZmQsIFFNQU5fRkRfQk1UX0VOQUJMRSk7CisJZHBhYTJf ZmRfc2V0X2Zvcm1hdChmZCwgUU1BTl9GRF9GTVRfRU5BQkxFIHwgUU1BTl9GRF9TTF9ESVNBQkxF KTsKKworCWRwYWEyX2ZkX3NldF9mcmMoZmQsIGZvcm1hdCB8IFFETUFfU0VSX0NUWCk7Cit9CisK Ky8qIGZpcnN0IGZyYW1lIGxpc3QgZm9yIGRlc2NyaXB0b3IgYnVmZmVyICovCitzdGF0aWMgdm9p ZAorZHBhYTJfcWRtYV9wb3B1bGF0ZV9maXJzdF9mcmFtZWwoc3RydWN0IGRwYWEyX2ZsX2VudHJ5 ICpmX2xpc3QsCisJCQkJIHN0cnVjdCBkcGFhMl9xZG1hX2NvbXAgKmRwYWEyX2NvbXAsCisJCQkJ IGJvb2wgd3J0X2NoYW5nZWQpCit7CisJc3RydWN0IGRwYWEyX3FkbWFfc2RfZCAqc2RkOworCisJ c2RkID0gKHN0cnVjdCBkcGFhMl9xZG1hX3NkX2QgKilkcGFhMl9jb21wLT5kZXNjX3ZpcnRfYWRk cjsKKwltZW1zZXQoc2RkLCAwLCAyICogKHNpemVvZigqc2RkKSkpOworCisJLyogc291cmNlIGRl c2NyaXB0b3IgQ01EICovCisJc2RkLT5jbWQgPSBjcHVfdG9fbGUzMihRRE1BX1NEX0NNRF9SRFRU WVBFX0NPSEVSRU5UKTsKKwlzZGQrKzsKKworCS8qIGRlc3QgZGVzY3JpcHRvciBDTUQgKi8KKwlp ZiAod3J0X2NoYW5nZWQpCisJCXNkZC0+Y21kID0gY3B1X3RvX2xlMzIoTFgyMTYwX1FETUFfRERf Q01EX1dSVFRZUEVfQ09IRVJFTlQpOworCWVsc2UKKwkJc2RkLT5jbWQgPSBjcHVfdG9fbGUzMihR RE1BX0REX0NNRF9XUlRUWVBFX0NPSEVSRU5UKTsKKworCW1lbXNldChmX2xpc3QsIDAsIHNpemVv ZihzdHJ1Y3QgZHBhYTJfZmxfZW50cnkpKTsKKworCS8qIGZpcnN0IGZyYW1lIGxpc3QgdG8gc291 cmNlIGRlc2NyaXB0b3IgKi8KKwlkcGFhMl9mbF9zZXRfYWRkcihmX2xpc3QsIGRwYWEyX2NvbXAt PmRlc2NfYnVzX2FkZHIpOworCWRwYWEyX2ZsX3NldF9sZW4oZl9saXN0LCAweDIwKTsKKwlkcGFh Ml9mbF9zZXRfZm9ybWF0KGZfbGlzdCwgUURNQV9GTF9GTVRfU0JGIHwgUURNQV9GTF9TTF9MT05H KTsKKworCS8qIGJ5cGFzcyBtZW1vcnkgdHJhbnNsYXRpb24gKi8KKwlpZiAoc21tdV9kaXNhYmxl KQorCQlmX2xpc3QtPmJwaWQgPSBjcHVfdG9fbGUxNihRRE1BX0ZMX0JNVF9FTkFCTEUpOworfQor CisvKiBzb3VyY2UgYW5kIGRlc3RpbmF0aW9uIGZyYW1lIGxpc3QgKi8KK3N0YXRpYyB2b2lkCitk cGFhMl9xZG1hX3BvcHVsYXRlX2ZyYW1lcyhzdHJ1Y3QgZHBhYTJfZmxfZW50cnkgKmZfbGlzdCwK KwkJCSAgIGRtYV9hZGRyX3QgZHN0LCBkbWFfYWRkcl90IHNyYywKKwkJCSAgIHNpemVfdCBsZW4s IHVpbnQ4X3QgZm10KQoreworCS8qIHNvdXJjZSBmcmFtZSBsaXN0IHRvIHNvdXJjZSBidWZmZXIg Ki8KKwltZW1zZXQoZl9saXN0LCAwLCBzaXplb2Yoc3RydWN0IGRwYWEyX2ZsX2VudHJ5KSk7CisK KwlkcGFhMl9mbF9zZXRfYWRkcihmX2xpc3QsIHNyYyk7CisJZHBhYTJfZmxfc2V0X2xlbihmX2xp c3QsIGxlbik7CisKKwkvKiBzaW5nbGUgYnVmZmVyIGZyYW1lIG9yIHNjYXR0ZXIgZ2F0aGVyIGZy YW1lICovCisJZHBhYTJfZmxfc2V0X2Zvcm1hdChmX2xpc3QsIChmbXQgfCBRRE1BX0ZMX1NMX0xP TkcpKTsKKworCS8qIGJ5cGFzcyBtZW1vcnkgdHJhbnNsYXRpb24gKi8KKwlpZiAoc21tdV9kaXNh YmxlKQorCQlmX2xpc3QtPmJwaWQgPSBjcHVfdG9fbGUxNihRRE1BX0ZMX0JNVF9FTkFCTEUpOwor CisJZl9saXN0Kys7CisKKwkvKiBkZXN0aW5hdGlvbiBmcmFtZSBsaXN0IHRvIGRlc3RpbmF0aW9u IGJ1ZmZlciAqLworCW1lbXNldChmX2xpc3QsIDAsIHNpemVvZihzdHJ1Y3QgZHBhYTJfZmxfZW50 cnkpKTsKKworCWRwYWEyX2ZsX3NldF9hZGRyKGZfbGlzdCwgZHN0KTsKKwlkcGFhMl9mbF9zZXRf bGVuKGZfbGlzdCwgbGVuKTsKKwlkcGFhMl9mbF9zZXRfZm9ybWF0KGZfbGlzdCwgKGZtdCB8IFFE TUFfRkxfU0xfTE9ORykpOworCS8qIHNpbmdsZSBidWZmZXIgZnJhbWUgb3Igc2NhdHRlciBnYXRo ZXIgZnJhbWUgKi8KKwlkcGFhMl9mbF9zZXRfZmluYWwoZl9saXN0LCBRRE1BX0ZMX0YpOworCS8q IGJ5cGFzcyBtZW1vcnkgdHJhbnNsYXRpb24gKi8KKwlpZiAoc21tdV9kaXNhYmxlKQorCQlmX2xp c3QtPmJwaWQgPSBjcHVfdG9fbGUxNihRRE1BX0ZMX0JNVF9FTkFCTEUpOworfQorCitzdGF0aWMg c3RydWN0IGRtYV9hc3luY190eF9kZXNjcmlwdG9yCisqZHBhYTJfcWRtYV9wcmVwX21lbWNweShz dHJ1Y3QgZG1hX2NoYW4gKmNoYW4sIGRtYV9hZGRyX3QgZHN0LAorCQkJZG1hX2FkZHJfdCBzcmMs IHNpemVfdCBsZW4sIHVsb25nIGZsYWdzKQoreworCXN0cnVjdCBkcGFhMl9xZG1hX2NoYW4gKmRw YWEyX2NoYW4gPSB0b19kcGFhMl9xZG1hX2NoYW4oY2hhbik7CisJc3RydWN0IGRwYWEyX3FkbWFf ZW5naW5lICpkcGFhMl9xZG1hOworCXN0cnVjdCBkcGFhMl9xZG1hX2NvbXAgKmRwYWEyX2NvbXA7 CisJc3RydWN0IGRwYWEyX2ZsX2VudHJ5ICpmX2xpc3Q7CisJYm9vbCB3cnRfY2hhbmdlZDsKKwl1 MzIgZm9ybWF0OworCisJZHBhYTJfcWRtYSA9IGRwYWEyX2NoYW4tPnFkbWE7CisJZHBhYTJfY29t cCA9IGRwYWEyX3FkbWFfcmVxdWVzdF9kZXNjKGRwYWEyX2NoYW4pOworCXdydF9jaGFuZ2VkID0g KGJvb2wpZHBhYTJfcWRtYS0+cWRtYV93cnR5cGVfZml4dXA7CisKKyNpZmRlZiBMT05HX0ZPUk1B VAorCWZvcm1hdCA9IFFETUFfRkRfTE9OR19GT1JNQVQ7CisjZWxzZQorCWZvcm1hdCA9IFFETUFf RkRfU0hPUlRfRk9STUFUOworI2VuZGlmCisJLyogcG9wdWxhdGUgRnJhbWUgZGVzY3JpcHRvciAq LworCWRwYWEyX3FkbWFfcG9wdWxhdGVfZmQoZm9ybWF0LCBkcGFhMl9jb21wKTsKKworCWZfbGlz dCA9IChzdHJ1Y3QgZHBhYTJfZmxfZW50cnkgKilkcGFhMl9jb21wLT5mbF92aXJ0X2FkZHI7CisK KyNpZmRlZiBMT05HX0ZPUk1BVAorCS8qIGZpcnN0IGZyYW1lIGxpc3QgZm9yIGRlc2NyaXB0b3Ig YnVmZmVyIChsb2duIGZvcm1hdCkgKi8KKwlkcGFhMl9xZG1hX3BvcHVsYXRlX2ZpcnN0X2ZyYW1l bChmX2xpc3QsIGRwYWEyX2NvbXAsIHdydF9jaGFuZ2VkKTsKKworCWZfbGlzdCsrOworI2VuZGlm CisKKwlkcGFhMl9xZG1hX3BvcHVsYXRlX2ZyYW1lcyhmX2xpc3QsIGRzdCwgc3JjLCBsZW4sIFFE TUFfRkxfRk1UX1NCRik7CisKKwlyZXR1cm4gdmNoYW5fdHhfcHJlcCgmZHBhYTJfY2hhbi0+dmNo YW4sICZkcGFhMl9jb21wLT52ZGVzYywgZmxhZ3MpOworfQorCitzdGF0aWMgZW51bQorZG1hX3N0 YXR1cyBkcGFhMl9xZG1hX3R4X3N0YXR1cyhzdHJ1Y3QgZG1hX2NoYW4gKmNoYW4sCisJCQkJZG1h X2Nvb2tpZV90IGNvb2tpZSwKKwkJCQlzdHJ1Y3QgZG1hX3R4X3N0YXRlICp0eHN0YXRlKQorewor CXJldHVybiBkbWFfY29va2llX3N0YXR1cyhjaGFuLCBjb29raWUsIHR4c3RhdGUpOworfQorCitz dGF0aWMgdm9pZCBkcGFhMl9xZG1hX2lzc3VlX3BlbmRpbmcoc3RydWN0IGRtYV9jaGFuICpjaGFu KQoreworCXN0cnVjdCBkcGFhMl9xZG1hX2NoYW4gKmRwYWEyX2NoYW4gPSB0b19kcGFhMl9xZG1h X2NoYW4oY2hhbik7CisJc3RydWN0IGRwYWEyX3FkbWFfZW5naW5lICpkcGFhMl9xZG1hID0gZHBh YTJfY2hhbi0+cWRtYTsKKwlzdHJ1Y3QgZHBhYTJfcWRtYV9wcml2ICpwcml2ID0gZHBhYTJfcWRt YS0+cHJpdjsKKwlzdHJ1Y3QgZHBhYTJfcWRtYV9jb21wICpkcGFhMl9jb21wOworCXN0cnVjdCB2 aXJ0X2RtYV9kZXNjICp2ZGVzYzsKKwlzdHJ1Y3QgZHBhYTJfZmQgKmZkOworCXVuc2lnbmVkIGxv bmcgZmxhZ3M7CisJaW50IGVycjsKKworCXNwaW5fbG9ja19pcnFzYXZlKCZkcGFhMl9jaGFuLT5x dWV1ZV9sb2NrLCBmbGFncyk7CisJc3Bpbl9sb2NrKCZkcGFhMl9jaGFuLT52Y2hhbi5sb2NrKTsK KwlpZiAodmNoYW5faXNzdWVfcGVuZGluZygmZHBhYTJfY2hhbi0+dmNoYW4pKSB7CisJCXZkZXNj ID0gdmNoYW5fbmV4dF9kZXNjKCZkcGFhMl9jaGFuLT52Y2hhbik7CisJCWlmICghdmRlc2MpCisJ CQlnb3RvIGVycl9lbnF1ZXVlOworCQlkcGFhMl9jb21wID0gdG9fZnNsX3FkbWFfY29tcCh2ZGVz Yyk7CisKKwkJZmQgPSAoc3RydWN0IGRwYWEyX2ZkICopZHBhYTJfY29tcC0+ZmRfdmlydF9hZGRy OworCisJCWxpc3RfZGVsKCZ2ZGVzYy0+bm9kZSk7CisJCWxpc3RfYWRkX3RhaWwoJmRwYWEyX2Nv bXAtPmxpc3QsICZkcGFhMl9jaGFuLT5jb21wX3VzZWQpOworCisJCS8qIFRPQk86IHByaW9yaXR5 IGhhcmQtY29kZWQgdG8gemVybyAqLworCQllcnIgPSBkcGFhMl9pb19zZXJ2aWNlX2VucXVldWVf ZnEoTlVMTCwKKwkJCQlwcml2LT50eF9xdWV1ZV9hdHRyWzBdLmZxaWQsIGZkKTsKKwkJaWYgKGVy cikgeworCQkJbGlzdF9kZWwoJmRwYWEyX2NvbXAtPmxpc3QpOworCQkJbGlzdF9hZGRfdGFpbCgm ZHBhYTJfY29tcC0+bGlzdCwKKwkJCQkgICAgICAmZHBhYTJfY2hhbi0+Y29tcF9mcmVlKTsKKwkJ fQorCX0KK2Vycl9lbnF1ZXVlOgorCXNwaW5fdW5sb2NrKCZkcGFhMl9jaGFuLT52Y2hhbi5sb2Nr KTsKKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZkcGFhMl9jaGFuLT5xdWV1ZV9sb2NrLCBmbGFn cyk7Cit9CisKK3N0YXRpYyBpbnQgX19jb2xkIGRwYWEyX3FkbWFfc2V0dXAoc3RydWN0IGZzbF9t Y19kZXZpY2UgKmxzX2RldikKK3sKKwlzdHJ1Y3QgZHBhYTJfcWRtYV9wcml2X3Blcl9wcmlvICpw cHJpdjsKKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmbHNfZGV2LT5kZXY7CisJc3RydWN0IGRwYWEy X3FkbWFfcHJpdiAqcHJpdjsKKwl1OCBwcmlvX2RlZiA9IERQRE1BSV9QUklPX05VTTsKKwlpbnQg ZXJyOworCWludCBpOworCisJcHJpdiA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOworCisJcHJpdi0+ ZGV2ID0gZGV2OworCXByaXYtPmRwcWRtYV9pZCA9IGxzX2Rldi0+b2JqX2Rlc2MuaWQ7CisKKwkv KkdldCB0aGUgaGFuZGxlIGZvciB0aGUgRFBETUFJIHRoaXMgaW50ZXJmYWNlIGlzIGFzc29jaWF0 ZSB3aXRoICovCisJZXJyID0gZHBkbWFpX29wZW4ocHJpdi0+bWNfaW8sIDAsIHByaXYtPmRwcWRt YV9pZCwgJmxzX2Rldi0+bWNfaGFuZGxlKTsKKwlpZiAoZXJyKSB7CisJCWRldl9lcnIoZGV2LCAi ZHBkbWFpX29wZW4oKSBmYWlsZWRcbiIpOworCQlyZXR1cm4gZXJyOworCX0KKwlkZXZfaW5mbyhk ZXYsICJPcGVuZWQgZHBkbWFpIG9iamVjdCBzdWNjZXNzZnVsbHlcbiIpOworCisJZXJyID0gZHBk bWFpX2dldF9hdHRyaWJ1dGVzKHByaXYtPm1jX2lvLCAwLCBsc19kZXYtPm1jX2hhbmRsZSwKKwkJ CQkgICAgJnByaXYtPmRwZG1haV9hdHRyKTsKKwlpZiAoZXJyKSB7CisJCWRldl9lcnIoZGV2LCAi ZHBkbWFpX2dldF9hdHRyaWJ1dGVzKCkgZmFpbGVkXG4iKTsKKwkJcmV0dXJuIGVycjsKKwl9CisK KwlpZiAocHJpdi0+ZHBkbWFpX2F0dHIudmVyc2lvbi5tYWpvciA+IERQRE1BSV9WRVJfTUFKT1Ip IHsKKwkJZGV2X2VycihkZXYsICJEUERNQUkgbWFqb3IgdmVyc2lvbiBtaXNtYXRjaFxuIgorCQkJ ICAgICAiRm91bmQgJXUuJXUsIHN1cHBvcnRlZCB2ZXJzaW9uIGlzICV1LiV1XG4iLAorCQkJCXBy aXYtPmRwZG1haV9hdHRyLnZlcnNpb24ubWFqb3IsCisJCQkJcHJpdi0+ZHBkbWFpX2F0dHIudmVy c2lvbi5taW5vciwKKwkJCQlEUERNQUlfVkVSX01BSk9SLCBEUERNQUlfVkVSX01JTk9SKTsKKwl9 CisKKwlpZiAocHJpdi0+ZHBkbWFpX2F0dHIudmVyc2lvbi5taW5vciA+IERQRE1BSV9WRVJfTUlO T1IpIHsKKwkJZGV2X2VycihkZXYsICJEUERNQUkgbWlub3IgdmVyc2lvbiBtaXNtYXRjaFxuIgor CQkJICAgICAiRm91bmQgJXUuJXUsIHN1cHBvcnRlZCB2ZXJzaW9uIGlzICV1LiV1XG4iLAorCQkJ CXByaXYtPmRwZG1haV9hdHRyLnZlcnNpb24ubWFqb3IsCisJCQkJcHJpdi0+ZHBkbWFpX2F0dHIu dmVyc2lvbi5taW5vciwKKwkJCQlEUERNQUlfVkVSX01BSk9SLCBEUERNQUlfVkVSX01JTk9SKTsK Kwl9CisKKwlwcml2LT5udW1fcGFpcnMgPSBtaW4ocHJpdi0+ZHBkbWFpX2F0dHIubnVtX29mX3By aW9yaXRpZXMsIHByaW9fZGVmKTsKKwlwcHJpdiA9IGtjYWxsb2MocHJpdi0+bnVtX3BhaXJzLCBz aXplb2YoKnBwcml2KSwgR0ZQX0tFUk5FTCk7CisJaWYgKCFwcHJpdikgeworCQlkZXZfZXJyKGRl diwgImt6YWxsb2MgZm9yIHBwcml2IGZhaWxlZFxuIik7CisJCXJldHVybiAtMTsKKwl9CisJcHJp di0+cHByaXYgPSBwcHJpdjsKKworCWZvciAoaSA9IDA7IGkgPCBwcml2LT5udW1fcGFpcnM7IGkr KykgeworCQllcnIgPSBkcGRtYWlfZ2V0X3J4X3F1ZXVlKHByaXYtPm1jX2lvLCAwLCBsc19kZXYt Pm1jX2hhbmRsZSwKKwkJCQkJICBpLCAmcHJpdi0+cnhfcXVldWVfYXR0cltpXSk7CisJCWlmIChl cnIpIHsKKwkJCWRldl9lcnIoZGV2LCAiZHBkbWFpX2dldF9yeF9xdWV1ZSgpIGZhaWxlZFxuIik7 CisJCQlyZXR1cm4gZXJyOworCQl9CisJCXBwcml2LT5yc3BfZnFpZCA9IHByaXYtPnJ4X3F1ZXVl X2F0dHJbaV0uZnFpZDsKKworCQllcnIgPSBkcGRtYWlfZ2V0X3R4X3F1ZXVlKHByaXYtPm1jX2lv LCAwLCBsc19kZXYtPm1jX2hhbmRsZSwKKwkJCQkJICBpLCAmcHJpdi0+dHhfcXVldWVfYXR0cltp XSk7CisJCWlmIChlcnIpIHsKKwkJCWRldl9lcnIoZGV2LCAiZHBkbWFpX2dldF90eF9xdWV1ZSgp IGZhaWxlZFxuIik7CisJCQlyZXR1cm4gZXJyOworCQl9CisJCXBwcml2LT5yZXFfZnFpZCA9IHBy aXYtPnR4X3F1ZXVlX2F0dHJbaV0uZnFpZDsKKwkJcHByaXYtPnByaW8gPSBpOworCQlwcHJpdi0+ cHJpdiA9IHByaXY7CisJCXBwcml2Kys7CisJfQorCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyB2 b2lkIGRwYWEyX3FkbWFfZnFkYW5fY2Ioc3RydWN0IGRwYWEyX2lvX25vdGlmaWNhdGlvbl9jdHgg KmN0eCkKK3sKKwlzdHJ1Y3QgZHBhYTJfcWRtYV9wcml2X3Blcl9wcmlvICpwcHJpdiA9IGNvbnRh aW5lcl9vZihjdHgsCisJCQlzdHJ1Y3QgZHBhYTJfcWRtYV9wcml2X3Blcl9wcmlvLCBuY3R4KTsK KwlzdHJ1Y3QgZHBhYTJfcWRtYV9jb21wICpkcGFhMl9jb21wLCAqX2NvbXBfdG1wOworCXN0cnVj dCBkcGFhMl9xZG1hX3ByaXYgKnByaXYgPSBwcHJpdi0+cHJpdjsKKwl1MzIgbl9jaGFucyA9IHBy aXYtPmRwYWEyX3FkbWEtPm5fY2hhbnM7CisJc3RydWN0IGRwYWEyX3FkbWFfY2hhbiAqcWNoYW47 CisJY29uc3Qgc3RydWN0IGRwYWEyX2ZkICpmZF9lcTsKKwljb25zdCBzdHJ1Y3QgZHBhYTJfZmQg KmZkOworCXN0cnVjdCBkcGFhMl9kcSAqZHE7CisJaW50IGlzX2xhc3QgPSAwOworCWludCBmb3Vu ZDsKKwl1OCBzdGF0dXM7CisJaW50IGVycjsKKwlpbnQgaTsKKworCWRvIHsKKwkJZXJyID0gZHBh YTJfaW9fc2VydmljZV9wdWxsX2ZxKE5VTEwsIHBwcml2LT5yc3BfZnFpZCwKKwkJCQkJICAgICAg IHBwcml2LT5zdG9yZSk7CisJfSB3aGlsZSAoZXJyKTsKKworCXdoaWxlICghaXNfbGFzdCkgewor CQlkbyB7CisJCQlkcSA9IGRwYWEyX2lvX3N0b3JlX25leHQocHByaXYtPnN0b3JlLCAmaXNfbGFz dCk7CisJCX0gd2hpbGUgKCFpc19sYXN0ICYmICFkcSk7CisJCWlmICghZHEpIHsKKwkJCWRldl9l cnIocHJpdi0+ZGV2LCAiRlFJRCByZXR1cm5lZCBubyB2YWxpZCBmcmFtZXMhXG4iKTsKKwkJCWNv bnRpbnVlOworCQl9CisKKwkJLyogb2J0YWluIEZEIGFuZCBwcm9jZXNzIHRoZSBlcnJvciAqLwor CQlmZCA9IGRwYWEyX2RxX2ZkKGRxKTsKKworCQlzdGF0dXMgPSBkcGFhMl9mZF9nZXRfY3RybChm ZCkgJiAweGZmOworCQlpZiAoc3RhdHVzKQorCQkJZGV2X2Vycihwcml2LT5kZXYsICJGRCBlcnJv ciBvY2N1cnJlZFxuIik7CisJCWZvdW5kID0gMDsKKwkJZm9yIChpID0gMDsgaSA8IG5fY2hhbnM7 IGkrKykgeworCQkJcWNoYW4gPSAmcHJpdi0+ZHBhYTJfcWRtYS0+Y2hhbnNbaV07CisJCQlzcGlu X2xvY2soJnFjaGFuLT5xdWV1ZV9sb2NrKTsKKwkJCWlmIChsaXN0X2VtcHR5KCZxY2hhbi0+Y29t cF91c2VkKSkgeworCQkJCXNwaW5fdW5sb2NrKCZxY2hhbi0+cXVldWVfbG9jayk7CisJCQkJY29u dGludWU7CisJCQl9CisJCQlsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoZHBhYTJfY29tcCwgX2Nv bXBfdG1wLAorCQkJCQkJICZxY2hhbi0+Y29tcF91c2VkLCBsaXN0KSB7CisJCQkJZmRfZXEgPSAo c3RydWN0IGRwYWEyX2ZkICopCisJCQkJCWRwYWEyX2NvbXAtPmZkX3ZpcnRfYWRkcjsKKworCQkJ CWlmIChsZTY0X3RvX2NwdShmZF9lcS0+c2ltcGxlLmFkZHIpID09CisJCQkJICAgIGxlNjRfdG9f Y3B1KGZkLT5zaW1wbGUuYWRkcikpIHsKKwkJCQkJc3Bpbl9sb2NrKCZxY2hhbi0+dmNoYW4ubG9j ayk7CisJCQkJCXZjaGFuX2Nvb2tpZV9jb21wbGV0ZSgmCisJCQkJCQkJZHBhYTJfY29tcC0+dmRl c2MpOworCQkJCQlzcGluX3VubG9jaygmcWNoYW4tPnZjaGFuLmxvY2spOworCQkJCQlmb3VuZCA9 IDE7CisJCQkJCWJyZWFrOworCQkJCX0KKwkJCX0KKwkJCXNwaW5fdW5sb2NrKCZxY2hhbi0+cXVl dWVfbG9jayk7CisJCQlpZiAoZm91bmQpCisJCQkJYnJlYWs7CisJCX0KKwl9CisKKwlkcGFhMl9p b19zZXJ2aWNlX3JlYXJtKE5VTEwsIGN0eCk7Cit9CisKK3N0YXRpYyBpbnQgX19jb2xkIGRwYWEy X3FkbWFfZHBpb19zZXR1cChzdHJ1Y3QgZHBhYTJfcWRtYV9wcml2ICpwcml2KQoreworCXN0cnVj dCBkcGFhMl9xZG1hX3ByaXZfcGVyX3ByaW8gKnBwcml2OworCXN0cnVjdCBkZXZpY2UgKmRldiA9 IHByaXYtPmRldjsKKwlpbnQgZXJyLCBpLCBudW07CisKKwludW0gPSBwcml2LT5udW1fcGFpcnM7 CisJcHByaXYgPSBwcml2LT5wcHJpdjsKKwlmb3IgKGkgPSAwOyBpIDwgbnVtOyBpKyspIHsKKwkJ cHByaXYtPm5jdHguaXNfY2RhbiA9IDA7CisJCXBwcml2LT5uY3R4LmRlc2lyZWRfY3B1ID0gMTsK KwkJcHByaXYtPm5jdHguaWQgPSBwcHJpdi0+cnNwX2ZxaWQ7CisJCXBwcml2LT5uY3R4LmNiID0g ZHBhYTJfcWRtYV9mcWRhbl9jYjsKKwkJZXJyID0gZHBhYTJfaW9fc2VydmljZV9yZWdpc3RlcihO VUxMLCAmcHByaXYtPm5jdHgsIGRldik7CisJCWlmIChlcnIpIHsKKwkJCWRldl9lcnIoZGV2LCAi Tm90aWZpY2F0aW9uIHJlZ2lzdGVyIGZhaWxlZFxuIik7CisJCQlnb3RvIGVycl9zZXJ2aWNlOwor CQl9CisKKwkJcHByaXYtPnN0b3JlID0KKwkJCWRwYWEyX2lvX3N0b3JlX2NyZWF0ZShEUEFBMl9R RE1BX1NUT1JFX1NJWkUsIGRldik7CisJCWlmICghcHByaXYtPnN0b3JlKSB7CisJCQlkZXZfZXJy KGRldiwgImRwYWEyX2lvX3N0b3JlX2NyZWF0ZSgpIGZhaWxlZFxuIik7CisJCQlnb3RvIGVycl9z dG9yZTsKKwkJfQorCisJCXBwcml2Kys7CisJfQorCXJldHVybiAwOworCitlcnJfc3RvcmU6CisJ ZHBhYTJfaW9fc2VydmljZV9kZXJlZ2lzdGVyKE5VTEwsICZwcHJpdi0+bmN0eCwgZGV2KTsKK2Vy cl9zZXJ2aWNlOgorCXBwcml2LS07CisJd2hpbGUgKHBwcml2ID49IHByaXYtPnBwcml2KSB7CisJ CWRwYWEyX2lvX3NlcnZpY2VfZGVyZWdpc3RlcihOVUxMLCAmcHByaXYtPm5jdHgsIGRldik7CisJ CWRwYWEyX2lvX3N0b3JlX2Rlc3Ryb3kocHByaXYtPnN0b3JlKTsKKwkJcHByaXYtLTsKKwl9CisJ cmV0dXJuIC0xOworfQorCitzdGF0aWMgdm9pZCBkcGFhMl9kcG1haV9zdG9yZV9mcmVlKHN0cnVj dCBkcGFhMl9xZG1hX3ByaXYgKnByaXYpCit7CisJc3RydWN0IGRwYWEyX3FkbWFfcHJpdl9wZXJf cHJpbyAqcHByaXYgPSBwcml2LT5wcHJpdjsKKwlpbnQgaTsKKworCWZvciAoaSA9IDA7IGkgPCBw cml2LT5udW1fcGFpcnM7IGkrKykgeworCQlkcGFhMl9pb19zdG9yZV9kZXN0cm95KHBwcml2LT5z dG9yZSk7CisJCXBwcml2Kys7CisJfQorfQorCitzdGF0aWMgdm9pZCBkcGFhMl9kcGRtYWlfZHBp b19mcmVlKHN0cnVjdCBkcGFhMl9xZG1hX3ByaXYgKnByaXYpCit7CisJc3RydWN0IGRwYWEyX3Fk bWFfcHJpdl9wZXJfcHJpbyAqcHByaXYgPSBwcml2LT5wcHJpdjsKKwlzdHJ1Y3QgZGV2aWNlICpk ZXYgPSBwcml2LT5kZXY7CisJaW50IGk7CisKKwlmb3IgKGkgPSAwOyBpIDwgcHJpdi0+bnVtX3Bh aXJzOyBpKyspIHsKKwkJZHBhYTJfaW9fc2VydmljZV9kZXJlZ2lzdGVyKE5VTEwsICZwcHJpdi0+ bmN0eCwgZGV2KTsKKwkJcHByaXYrKzsKKwl9Cit9CisKK3N0YXRpYyBpbnQgX19jb2xkIGRwYWEy X2RwZG1haV9iaW5kKHN0cnVjdCBkcGFhMl9xZG1hX3ByaXYgKnByaXYpCit7CisJaW50IGVycjsK KwlpbnQgaSwgbnVtOworCXN0cnVjdCBkZXZpY2UgKmRldiA9IHByaXYtPmRldjsKKwlzdHJ1Y3Qg ZHBhYTJfcWRtYV9wcml2X3Blcl9wcmlvICpwcHJpdjsKKwlzdHJ1Y3QgZHBkbWFpX3J4X3F1ZXVl X2NmZyByeF9xdWV1ZV9jZmc7CisJc3RydWN0IGZzbF9tY19kZXZpY2UgKmxzX2RldiA9IHRvX2Zz bF9tY19kZXZpY2UoZGV2KTsKKworCW51bSA9IHByaXYtPm51bV9wYWlyczsKKwlwcHJpdiA9IHBy aXYtPnBwcml2OworCWZvciAoaSA9IDA7IGkgPCBudW07IGkrKykgeworCQlyeF9xdWV1ZV9jZmcu b3B0aW9ucyA9IERQRE1BSV9RVUVVRV9PUFRfVVNFUl9DVFggfAorCQkJCQlEUERNQUlfUVVFVUVf T1BUX0RFU1Q7CisJCXJ4X3F1ZXVlX2NmZy51c2VyX2N0eCA9IHBwcml2LT5uY3R4LnFtYW42NDsK KwkJcnhfcXVldWVfY2ZnLmRlc3RfY2ZnLmRlc3RfdHlwZSA9IERQRE1BSV9ERVNUX0RQSU87CisJ CXJ4X3F1ZXVlX2NmZy5kZXN0X2NmZy5kZXN0X2lkID0gcHByaXYtPm5jdHguZHBpb19pZDsKKwkJ cnhfcXVldWVfY2ZnLmRlc3RfY2ZnLnByaW9yaXR5ID0gcHByaXYtPnByaW87CisJCWVyciA9IGRw ZG1haV9zZXRfcnhfcXVldWUocHJpdi0+bWNfaW8sIDAsIGxzX2Rldi0+bWNfaGFuZGxlLAorCQkJ CQkgIHJ4X3F1ZXVlX2NmZy5kZXN0X2NmZy5wcmlvcml0eSwKKwkJCQkJICAmcnhfcXVldWVfY2Zn KTsKKwkJaWYgKGVycikgeworCQkJZGV2X2VycihkZXYsICJkcGRtYWlfc2V0X3J4X3F1ZXVlKCkg ZmFpbGVkXG4iKTsKKwkJCXJldHVybiBlcnI7CisJCX0KKworCQlwcHJpdisrOworCX0KKworCXJl dHVybiAwOworfQorCitzdGF0aWMgaW50IF9fY29sZCBkcGFhMl9kcGRtYWlfZHBpb191bmJpbmQo c3RydWN0IGRwYWEyX3FkbWFfcHJpdiAqcHJpdikKK3sKKwlpbnQgaTsKKwlpbnQgZXJyID0gMDsK KwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSBwcml2LT5kZXY7CisJc3RydWN0IGZzbF9tY19kZXZpY2Ug KmxzX2RldiA9IHRvX2ZzbF9tY19kZXZpY2UoZGV2KTsKKwlzdHJ1Y3QgZHBhYTJfcWRtYV9wcml2 X3Blcl9wcmlvICpwcHJpdiA9IHByaXYtPnBwcml2OworCisJZm9yIChpID0gMDsgaSA8IHByaXYt Pm51bV9wYWlyczsgaSsrKSB7CisJCXBwcml2LT5uY3R4LnFtYW42NCA9IDA7CisJCXBwcml2LT5u Y3R4LmRwaW9faWQgPSAwOworCQlwcHJpdisrOworCX0KKworCWVyciA9IGRwZG1haV9yZXNldChw cml2LT5tY19pbywgMCwgbHNfZGV2LT5tY19oYW5kbGUpOworCWlmIChlcnIpCisJCWRldl9lcnIo ZGV2LCAiZHBkbWFpX3Jlc2V0KCkgZmFpbGVkXG4iKTsKKworCXJldHVybiBlcnI7Cit9CisKK3N0 YXRpYyB2b2lkIGRwYWEyX2RwZG1haV9mcmVlX2NvbXAoc3RydWN0IGRwYWEyX3FkbWFfY2hhbiAq cWNoYW4sCisJCQkJICAgc3RydWN0IGxpc3RfaGVhZCAqaGVhZCkKK3sKKwlzdHJ1Y3QgZHBhYTJf cWRtYV9jb21wICpjb21wX3RtcCwgKl9jb21wX3RtcDsKKworCWxpc3RfZm9yX2VhY2hfZW50cnlf c2FmZShjb21wX3RtcCwgX2NvbXBfdG1wLAorCQkJCSBoZWFkLCBsaXN0KSB7CisJCWRtYV9wb29s X2ZyZWUocWNoYW4tPmZkX3Bvb2wsCisJCQkgICAgICBjb21wX3RtcC0+ZmRfdmlydF9hZGRyLAor CQkJICAgICAgY29tcF90bXAtPmZkX2J1c19hZGRyKTsKKwkJbGlzdF9kZWwoJmNvbXBfdG1wLT5s aXN0KTsKKwkJa2ZyZWUoY29tcF90bXApOworCX0KK30KKworc3RhdGljIHZvaWQgZHBhYTJfZHBk bWFpX2ZyZWVfY2hhbm5lbHMoc3RydWN0IGRwYWEyX3FkbWFfZW5naW5lICpkcGFhMl9xZG1hKQor eworCXN0cnVjdCBkcGFhMl9xZG1hX2NoYW4gKnFjaGFuOworCWludCBudW0sIGk7CisKKwludW0g PSBkcGFhMl9xZG1hLT5uX2NoYW5zOworCWZvciAoaSA9IDA7IGkgPCBudW07IGkrKykgeworCQlx Y2hhbiA9ICZkcGFhMl9xZG1hLT5jaGFuc1tpXTsKKwkJZHBhYTJfZHBkbWFpX2ZyZWVfY29tcChx Y2hhbiwgJnFjaGFuLT5jb21wX3VzZWQpOworCQlkcGFhMl9kcGRtYWlfZnJlZV9jb21wKHFjaGFu LCAmcWNoYW4tPmNvbXBfZnJlZSk7CisJCWRtYV9wb29sX2Rlc3Ryb3kocWNoYW4tPmZkX3Bvb2wp OworCX0KK30KKworc3RhdGljIHZvaWQgZHBhYTJfcWRtYV9mcmVlX2Rlc2Moc3RydWN0IHZpcnRf ZG1hX2Rlc2MgKnZkZXNjKQoreworCXN0cnVjdCBkcGFhMl9xZG1hX2NvbXAgKmRwYWEyX2NvbXA7 CisJc3RydWN0IGRwYWEyX3FkbWFfY2hhbiAqcWNoYW47CisKKwlkcGFhMl9jb21wID0gdG9fZnNs X3FkbWFfY29tcCh2ZGVzYyk7CisJcWNoYW4gPSBkcGFhMl9jb21wLT5xY2hhbjsKKwlsaXN0X2Rl bCgmZHBhYTJfY29tcC0+bGlzdCk7CisJbGlzdF9hZGRfdGFpbCgmZHBhYTJfY29tcC0+bGlzdCwg JnFjaGFuLT5jb21wX2ZyZWUpOworfQorCitzdGF0aWMgaW50IGRwYWEyX2RwZG1haV9pbml0X2No YW5uZWxzKHN0cnVjdCBkcGFhMl9xZG1hX2VuZ2luZSAqZHBhYTJfcWRtYSkKK3sKKwlzdHJ1Y3Qg ZHBhYTJfcWRtYV9jaGFuICpkcGFhMl9jaGFuOworCWludCBpOworCisJSU5JVF9MSVNUX0hFQUQo JmRwYWEyX3FkbWEtPmRtYV9kZXYuY2hhbm5lbHMpOworCWZvciAoaSA9IDA7IGkgPCBkcGFhMl9x ZG1hLT5uX2NoYW5zOyBpKyspIHsKKwkJZHBhYTJfY2hhbiA9ICZkcGFhMl9xZG1hLT5jaGFuc1tp XTsKKwkJZHBhYTJfY2hhbi0+cWRtYSA9IGRwYWEyX3FkbWE7CisJCWRwYWEyX2NoYW4tPnZjaGFu LmRlc2NfZnJlZSA9IGRwYWEyX3FkbWFfZnJlZV9kZXNjOworCQl2Y2hhbl9pbml0KCZkcGFhMl9j aGFuLT52Y2hhbiwgJmRwYWEyX3FkbWEtPmRtYV9kZXYpOworCQlzcGluX2xvY2tfaW5pdCgmZHBh YTJfY2hhbi0+cXVldWVfbG9jayk7CisJCUlOSVRfTElTVF9IRUFEKCZkcGFhMl9jaGFuLT5jb21w X3VzZWQpOworCQlJTklUX0xJU1RfSEVBRCgmZHBhYTJfY2hhbi0+Y29tcF9mcmVlKTsKKwl9CisJ cmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgZHBhYTJfcWRtYV9wcm9iZShzdHJ1Y3QgZnNsX21j X2RldmljZSAqZHBkbWFpX2RldikKK3sKKwlzdHJ1Y3QgZHBhYTJfcWRtYV9wcml2ICpwcml2Owor CXN0cnVjdCBkZXZpY2UgKmRldiA9ICZkcGRtYWlfZGV2LT5kZXY7CisJc3RydWN0IGRwYWEyX3Fk bWFfZW5naW5lICpkcGFhMl9xZG1hOworCWludCBlcnI7CisKKwlwcml2ID0ga3phbGxvYyhzaXpl b2YoKnByaXYpLCBHRlBfS0VSTkVMKTsKKwlpZiAoIXByaXYpCisJCXJldHVybiAtRU5PTUVNOwor CWRldl9zZXRfZHJ2ZGF0YShkZXYsIHByaXYpOworCXByaXYtPmRwZG1haV9kZXYgPSBkcGRtYWlf ZGV2OworCisJcHJpdi0+aW9tbXVfZG9tYWluID0gaW9tbXVfZ2V0X2RvbWFpbl9mb3JfZGV2KGRl dik7CisJaWYgKHByaXYtPmlvbW11X2RvbWFpbikKKwkJc21tdV9kaXNhYmxlID0gZmFsc2U7CisK KwkvKiBvYnRhaW4gYSBNQyBwb3J0YWwgKi8KKwllcnIgPSBmc2xfbWNfcG9ydGFsX2FsbG9jYXRl KGRwZG1haV9kZXYsIDAsICZwcml2LT5tY19pbyk7CisJaWYgKGVycikgeworCQlpZiAoZXJyID09 IC1FTlhJTykKKwkJCWVyciA9IC1FUFJPQkVfREVGRVI7CisJCWVsc2UKKwkJCWRldl9lcnIoZGV2 LCAiTUMgcG9ydGFsIGFsbG9jYXRpb24gZmFpbGVkXG4iKTsKKwkJZ290byBlcnJfbWNwb3J0YWw7 CisJfQorCisJLyogRFBETUFJIGluaXRpYWxpemF0aW9uICovCisJZXJyID0gZHBhYTJfcWRtYV9z ZXR1cChkcGRtYWlfZGV2KTsKKwlpZiAoZXJyKSB7CisJCWRldl9lcnIoZGV2LCAiZHBhYTJfZHBk bWFpX3NldHVwKCkgZmFpbGVkXG4iKTsKKwkJZ290byBlcnJfZHBkbWFpX3NldHVwOworCX0KKwor CS8qIERQSU8gKi8KKwllcnIgPSBkcGFhMl9xZG1hX2RwaW9fc2V0dXAocHJpdik7CisJaWYgKGVy cikgeworCQlkZXZfZXJyKGRldiwgImRwYWEyX2RwZG1haV9kcGlvX3NldHVwKCkgZmFpbGVkXG4i KTsKKwkJZ290byBlcnJfZHBpb19zZXR1cDsKKwl9CisKKwkvKiBEUERNQUkgYmluZGluZyB0byBE UElPICovCisJZXJyID0gZHBhYTJfZHBkbWFpX2JpbmQocHJpdik7CisJaWYgKGVycikgeworCQlk ZXZfZXJyKGRldiwgImRwYWEyX2RwZG1haV9iaW5kKCkgZmFpbGVkXG4iKTsKKwkJZ290byBlcnJf YmluZDsKKwl9CisKKwkvKiBEUERNQUkgZW5hYmxlICovCisJZXJyID0gZHBkbWFpX2VuYWJsZShw cml2LT5tY19pbywgMCwgZHBkbWFpX2Rldi0+bWNfaGFuZGxlKTsKKwlpZiAoZXJyKSB7CisJCWRl dl9lcnIoZGV2LCAiZHBkbWFpX2VuYWJsZSgpIGZhaWxlXG4iKTsKKwkJZ290byBlcnJfZW5hYmxl OworCX0KKworCWRwYWEyX3FkbWEgPSBremFsbG9jKHNpemVvZigqZHBhYTJfcWRtYSksIEdGUF9L RVJORUwpOworCWlmICghZHBhYTJfcWRtYSkgeworCQllcnIgPSAtRU5PTUVNOworCQlnb3RvIGVy cl9lbmc7CisJfQorCisJcHJpdi0+ZHBhYTJfcWRtYSA9IGRwYWEyX3FkbWE7CisJZHBhYTJfcWRt YS0+cHJpdiA9IHByaXY7CisKKwlkcGFhMl9xZG1hLT5kZXNjX2FsbG9jYXRlZCA9IDA7CisJZHBh YTJfcWRtYS0+bl9jaGFucyA9IE5VTV9DSDsKKworCWRwYWEyX2RwZG1haV9pbml0X2NoYW5uZWxz KGRwYWEyX3FkbWEpOworCisJaWYgKHNvY19kZXZpY2VfbWF0Y2goc29jX2ZpeHVwX3R1bmluZykp CisJCWRwYWEyX3FkbWEtPnFkbWFfd3J0eXBlX2ZpeHVwID0gdHJ1ZTsKKwllbHNlCisJCWRwYWEy X3FkbWEtPnFkbWFfd3J0eXBlX2ZpeHVwID0gZmFsc2U7CisKKwlkbWFfY2FwX3NldChETUFfUFJJ VkFURSwgZHBhYTJfcWRtYS0+ZG1hX2Rldi5jYXBfbWFzayk7CisJZG1hX2NhcF9zZXQoRE1BX1NM QVZFLCBkcGFhMl9xZG1hLT5kbWFfZGV2LmNhcF9tYXNrKTsKKwlkbWFfY2FwX3NldChETUFfTUVN Q1BZLCBkcGFhMl9xZG1hLT5kbWFfZGV2LmNhcF9tYXNrKTsKKworCWRwYWEyX3FkbWEtPmRtYV9k ZXYuZGV2ID0gZGV2OworCWRwYWEyX3FkbWEtPmRtYV9kZXYuZGV2aWNlX2FsbG9jX2NoYW5fcmVz b3VyY2VzID0KKwkJZHBhYTJfcWRtYV9hbGxvY19jaGFuX3Jlc291cmNlczsKKwlkcGFhMl9xZG1h LT5kbWFfZGV2LmRldmljZV9mcmVlX2NoYW5fcmVzb3VyY2VzID0KKwkJZHBhYTJfcWRtYV9mcmVl X2NoYW5fcmVzb3VyY2VzOworCWRwYWEyX3FkbWEtPmRtYV9kZXYuZGV2aWNlX3R4X3N0YXR1cyA9 IGRwYWEyX3FkbWFfdHhfc3RhdHVzOworCWRwYWEyX3FkbWEtPmRtYV9kZXYuZGV2aWNlX3ByZXBf ZG1hX21lbWNweSA9IGRwYWEyX3FkbWFfcHJlcF9tZW1jcHk7CisJZHBhYTJfcWRtYS0+ZG1hX2Rl di5kZXZpY2VfaXNzdWVfcGVuZGluZyA9IGRwYWEyX3FkbWFfaXNzdWVfcGVuZGluZzsKKworCWVy ciA9IGRtYV9hc3luY19kZXZpY2VfcmVnaXN0ZXIoJmRwYWEyX3FkbWEtPmRtYV9kZXYpOworCWlm IChlcnIpIHsKKwkJZGV2X2VycihkZXYsICJDYW4ndCByZWdpc3RlciBOWFAgUURNQSBlbmdpbmUu XG4iKTsKKwkJZ290byBlcnJfZW5nOworCX0KKworCXJldHVybiAwOworCitlcnJfZW5nOgorCWRw ZG1haV9kaXNhYmxlKHByaXYtPm1jX2lvLCAwLCBkcGRtYWlfZGV2LT5tY19oYW5kbGUpOworZXJy X2VuYWJsZToKKwlkcGFhMl9kcGRtYWlfZHBpb191bmJpbmQocHJpdik7CitlcnJfYmluZDoKKwlk cGFhMl9kcG1haV9zdG9yZV9mcmVlKHByaXYpOworCWRwYWEyX2RwZG1haV9kcGlvX2ZyZWUocHJp dik7CitlcnJfZHBpb19zZXR1cDoKKwlkcGRtYWlfY2xvc2UocHJpdi0+bWNfaW8sIDAsIGRwZG1h aV9kZXYtPm1jX2hhbmRsZSk7CitlcnJfZHBkbWFpX3NldHVwOgorCWZzbF9tY19wb3J0YWxfZnJl ZShwcml2LT5tY19pbyk7CitlcnJfbWNwb3J0YWw6CisJa2ZyZWUocHJpdi0+cHByaXYpOworCWtm cmVlKHByaXYpOworCWRldl9zZXRfZHJ2ZGF0YShkZXYsIE5VTEwpOworCXJldHVybiBlcnI7Cit9 CisKK3N0YXRpYyBpbnQgZHBhYTJfcWRtYV9yZW1vdmUoc3RydWN0IGZzbF9tY19kZXZpY2UgKmxz X2RldikKK3sKKwlzdHJ1Y3QgZGV2aWNlICpkZXY7CisJc3RydWN0IGRwYWEyX3FkbWFfcHJpdiAq cHJpdjsKKwlzdHJ1Y3QgZHBhYTJfcWRtYV9lbmdpbmUgKmRwYWEyX3FkbWE7CisKKwlkZXYgPSAm bHNfZGV2LT5kZXY7CisJcHJpdiA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOworCWRwYWEyX3FkbWEg PSBwcml2LT5kcGFhMl9xZG1hOworCisJZHBkbWFpX2Rpc2FibGUocHJpdi0+bWNfaW8sIDAsIGxz X2Rldi0+bWNfaGFuZGxlKTsKKwlkcGFhMl9kcGRtYWlfZHBpb191bmJpbmQocHJpdik7CisJZHBh YTJfZHBtYWlfc3RvcmVfZnJlZShwcml2KTsKKwlkcGFhMl9kcGRtYWlfZHBpb19mcmVlKHByaXYp OworCWRwZG1haV9jbG9zZShwcml2LT5tY19pbywgMCwgbHNfZGV2LT5tY19oYW5kbGUpOworCWZz bF9tY19wb3J0YWxfZnJlZShwcml2LT5tY19pbyk7CisJZGV2X3NldF9kcnZkYXRhKGRldiwgTlVM TCk7CisJZHBhYTJfZHBkbWFpX2ZyZWVfY2hhbm5lbHMoZHBhYTJfcWRtYSk7CisKKwlkbWFfYXN5 bmNfZGV2aWNlX3VucmVnaXN0ZXIoJmRwYWEyX3FkbWEtPmRtYV9kZXYpOworCWtmcmVlKHByaXYp OworCWtmcmVlKGRwYWEyX3FkbWEpOworCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBjb25zdCBz dHJ1Y3QgZnNsX21jX2RldmljZV9pZCBkcGFhMl9xZG1hX2lkX3RhYmxlW10gPSB7CisJeworCQku dmVuZG9yID0gRlNMX01DX1ZFTkRPUl9GUkVFU0NBTEUsCisJCS5vYmpfdHlwZSA9ICJkcGRtYWki LAorCX0sCisJeyAudmVuZG9yID0gMHgwIH0KK307CisKK3N0YXRpYyBzdHJ1Y3QgZnNsX21jX2Ry aXZlciBkcGFhMl9xZG1hX2RyaXZlciA9IHsKKwkuZHJpdmVyCQk9IHsKKwkJLm5hbWUJPSAiZHBh YTItcWRtYSIsCisJCS5vd25lciAgPSBUSElTX01PRFVMRSwKKwl9LAorCS5wcm9iZSAgICAgICAg ICA9IGRwYWEyX3FkbWFfcHJvYmUsCisJLnJlbW92ZQkJPSBkcGFhMl9xZG1hX3JlbW92ZSwKKwku bWF0Y2hfaWRfdGFibGUJPSBkcGFhMl9xZG1hX2lkX3RhYmxlCit9OworCitzdGF0aWMgaW50IF9f aW5pdCBkcGFhMl9xZG1hX2RyaXZlcl9pbml0KHZvaWQpCit7CisJcmV0dXJuIGZzbF9tY19kcml2 ZXJfcmVnaXN0ZXIoJihkcGFhMl9xZG1hX2RyaXZlcikpOworfQorbGF0ZV9pbml0Y2FsbChkcGFh Ml9xZG1hX2RyaXZlcl9pbml0KTsKKworc3RhdGljIHZvaWQgX19leGl0IGZzbF9xZG1hX2V4aXQo dm9pZCkKK3sKKwlmc2xfbWNfZHJpdmVyX3VucmVnaXN0ZXIoJihkcGFhMl9xZG1hX2RyaXZlcikp OworfQorbW9kdWxlX2V4aXQoZnNsX3FkbWFfZXhpdCk7CisKK01PRFVMRV9BTElBUygicGxhdGZv cm06ZnNsLWRwYWEyLXFkbWEiKTsKK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsKK01PRFVMRV9E RVNDUklQVElPTigiTlhQIExheWVyc2NhcGUgRFBBQTIgcURNQSBlbmdpbmUgZHJpdmVyIik7CmRp ZmYgLS1naXQgYS9kcml2ZXJzL2RtYS9mc2wtZHBhYTItcWRtYS9kcGFhMi1xZG1hLmggYi9kcml2 ZXJzL2RtYS9mc2wtZHBhYTItcWRtYS9kcGFhMi1xZG1hLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQK aW5kZXggMDAwMDAwMC4uM2ZjYWRlOAotLS0gL2Rldi9udWxsCisrKyBiL2RyaXZlcnMvZG1hL2Zz bC1kcGFhMi1xZG1hL2RwYWEyLXFkbWEuaApAQCAtMCwwICsxLDE1MiBAQAorLyogU1BEWC1MaWNl bnNlLUlkZW50aWZpZXI6IEdQTC0yLjAgKi8KKy8qIENvcHlyaWdodCAyMDE0LTIwMTggTlhQICov CisKKyNpZm5kZWYgX19EUEFBMl9RRE1BX0gKKyNkZWZpbmUgX19EUEFBMl9RRE1BX0gKKworI2Rl ZmluZSBMT05HX0ZPUk1BVCAxCisKKyNkZWZpbmUgRFBBQTJfUURNQV9TVE9SRV9TSVpFIDE2Cisj ZGVmaW5lIE5VTV9DSCA4CisKK3N0cnVjdCBkcGFhMl9xZG1hX3NkX2QgeworCXUzMiByc3Y6MzI7 CisJdW5pb24geworCQlzdHJ1Y3QgeworCQkJdTMyIHNzZDoxMjsgLyogc291Y2Ugc3RyaWRlIGRp c3RhbmNlICovCisJCQl1MzIgc3NzOjEyOyAvKiBzb3VjZSBzdHJpZGUgc2l6ZSAqLworCQkJdTMy IHJzdjE6ODsKKwkJfSBzZGY7CisJCXN0cnVjdCB7CisJCQl1MzIgZHNkOjEyOyAvKiBEZXN0aW5h dGlvbiBzdHJpZGUgZGlzdGFuY2UgKi8KKwkJCXUzMiBkc3M6MTI7IC8qIERlc3RpbmF0aW9uIHN0 cmlkZSBzaXplICovCisJCQl1MzIgcnN2Mjo4OworCQl9IGRkZjsKKwl9IGRmOworCXUzMiByYnBj bWQ7CS8qIFJvdXRlLWJ5LXBvcnQgY29tbWFuZCAqLworCXUzMiBjbWQ7Cit9IF9fYXR0cmlidXRl X18oKF9fcGFja2VkX18pKTsKKworLyogU291cmNlIGRlc2NyaXB0b3IgY29tbWFuZCByZWFkIHRy YW5zYWN0aW9uIHR5cGUgZm9yIFJCUD0wOiAqLworLyogY29oZXJlbnQgY29weSBvZiBjYWNoZWFi bGUgbWVtb3J5ICovCisjZGVmaW5lIFFETUFfU0RfQ01EX1JEVFRZUEVfQ09IRVJFTlQgKDB4YiA8 PCAyOCkKKy8qIERlc3RpbmF0aW9uIGRlc2NyaXB0b3IgY29tbWFuZCB3cml0ZSB0cmFuc2FjdGlv biB0eXBlIGZvciBSQlA9MDogKi8KKy8qIGNvaGVyZW50IGNvcHkgb2YgY2FjaGVhYmxlIG1lbW9y eSAqLworI2RlZmluZSBRRE1BX0REX0NNRF9XUlRUWVBFX0NPSEVSRU5UICgweDYgPDwgMjgpCisj ZGVmaW5lIExYMjE2MF9RRE1BX0REX0NNRF9XUlRUWVBFX0NPSEVSRU5UICgweGIgPDwgMjgpCisK KyNkZWZpbmUgUU1BTl9GRF9GTVRfRU5BQkxFCUJJVCgwKSAvKiBmcmFtZSBsaXN0IHRhYmxlIGVu YWJsZSAqLworI2RlZmluZSBRTUFOX0ZEX0JNVF9FTkFCTEUJQklUKDE1KSAvKiBieXBhc3MgbWVt b3J5IHRyYW5zbGF0aW9uICovCisjZGVmaW5lIFFNQU5fRkRfQk1UX0RJU0FCTEUJKDApIC8qIGJ5 cGFzcyBtZW1vcnkgdHJhbnNsYXRpb24gKi8KKyNkZWZpbmUgUU1BTl9GRF9TTF9ESVNBQkxFCSgw KSAvKiBzaG9ydCBsZW5ndGhlIGRpc2FibGVkICovCisjZGVmaW5lIFFNQU5fRkRfU0xfRU5BQkxF CUJJVCgxNCkgLyogc2hvcnQgbGVuZ3RoZSBlbmFibGVkICovCisKKyNkZWZpbmUgUURNQV9GSU5B TF9CSVRfRElTQUJMRQkoMCkgLyogZmluYWwgYml0IGRpc2FibGUgKi8KKyNkZWZpbmUgUURNQV9G SU5BTF9CSVRfRU5BQkxFCUJJVCgzMSkgLyogZmluYWwgYml0IGVuYWJsZSAqLworCisjZGVmaW5l IFFETUFfRkRfU0hPUlRfRk9STUFUCUJJVCgxMSkgLyogc2hvcnQgZm9ybWF0ICovCisjZGVmaW5l IFFETUFfRkRfTE9OR19GT1JNQVQJKDApIC8qIGxvbmcgZm9ybWF0ICovCisjZGVmaW5lIFFETUFf U0VSX0RJU0FCTEUJKDgpIC8qIG5vIG5vdGlmaWNhdGlvbiAqLworI2RlZmluZSBRRE1BX1NFUl9D VFgJCUJJVCg4KSAvKiBub3RpZmljYXRpb24gYnkgRlFEX0NUWFtmcWlkXSAqLworI2RlZmluZSBR RE1BX1NFUl9ERVNUCQkoMiA8PCA4KSAvKiBub3RpZmljYXRpb24gYnkgZGVzdGluYXRpb24gZGVz YyAqLworI2RlZmluZSBRRE1BX1NFUl9CT1RICQkoMyA8PCA4KSAvKiBzb3J1Y2UgYW5kIGRlc3Qg bm90aWZpY2F0aW9uICovCisjZGVmaW5lIFFETUFfRkRfU1BGX0VOQUxCRQlCSVQoMzApIC8qIHNv dXJjZSBwcmVmZXRjaCBlbmFibGUgKi8KKworI2RlZmluZSBRTUFOX0ZEX1ZBX0VOQUJMRQlCSVQo MTQpIC8qIEFkZHJlc3MgdXNlZCBpcyB2aXJ0dWFsIGFkZHJlc3MgKi8KKyNkZWZpbmUgUU1BTl9G RF9WQV9ESVNBQkxFCSgwKS8qIEFkZHJlc3MgdXNlZCBpcyBhIHJlYWwgYWRkcmVzcyAqLworLyog RmxvdyBDb250ZXh0OiA0OWJpdCBwaHlzaWNhbCBhZGRyZXNzICovCisjZGVmaW5lIFFNQU5fRkRf Q0JNVF9FTkFCTEUJQklUKDE1KQorI2RlZmluZSBRTUFOX0ZEX0NCTVRfRElTQUJMRQkoMCkgLyog RmxvdyBDb250ZXh0OiA2NGJpdCB2aXJ0dWFsIGFkZHJlc3MgKi8KKyNkZWZpbmUgUU1BTl9GRF9T Q19ESVNBQkxFCSgwKSAvKiBzdGFzaGluZyBjb250cm9sICovCisKKyNkZWZpbmUgUURNQV9GTF9G TVRfU0JGCQkoMHgwKSAvKiBTaW5nbGUgYnVmZmVyIGZyYW1lICovCisjZGVmaW5lIFFETUFfRkxf Rk1UX1NHRQkJKDB4MikgLyogU2NhdHRlciBnYXRoZXIgZnJhbWUgKi8KKyNkZWZpbmUgUURNQV9G TF9CTVRfRU5BQkxFCUJJVCgxNSkgLyogZW5hYmxlIGJ5cGFzcyBtZW1vcnkgdHJhbnNsYXRpb24g Ki8KKyNkZWZpbmUgUURNQV9GTF9CTVRfRElTQUJMRQkoMHgwKSAvKiBlbmFibGUgYnlwYXNzIG1l bW9yeSB0cmFuc2xhdGlvbiAqLworI2RlZmluZSBRRE1BX0ZMX1NMX0xPTkcJCSgweDApLyogbG9u ZyBsZW5ndGggKi8KKyNkZWZpbmUgUURNQV9GTF9TTF9TSE9SVAkoMHgxKSAvKiBzaG9ydCBsZW5n dGggKi8KKyNkZWZpbmUgUURNQV9GTF9GCQkoMHgxKS8qIGxhc3QgZnJhbWUgbGlzdCBiaXQgKi8K KworLypEZXNjcmlwdGlvbiBvZiBGcmFtZSBsaXN0IHRhYmxlIHN0cnVjdHVyZSovCitzdHJ1Y3Qg ZHBhYTJfcWRtYV9jaGFuIHsKKwlzdHJ1Y3QgdmlydF9kbWFfY2hhbgkJdmNoYW47CisJc3RydWN0 IHZpcnRfZG1hX2Rlc2MJCXZkZXNjOworCWVudW0gZG1hX3N0YXR1cwkJCXN0YXR1czsKKwlzdHJ1 Y3QgZHBhYTJfcWRtYV9lbmdpbmUJKnFkbWE7CisKKwlzdHJ1Y3QgbXV0ZXgJCQlkcGFhMl9xdWV1 ZV9tdXRleDsKKwlzcGlubG9ja190CQkJcXVldWVfbG9jazsKKwlzdHJ1Y3QgZG1hX3Bvb2wJCQkq ZmRfcG9vbDsKKworCXN0cnVjdCBsaXN0X2hlYWQJCWNvbXBfdXNlZDsKKwlzdHJ1Y3QgbGlzdF9o ZWFkCQljb21wX2ZyZWU7CisKK307CisKK3N0cnVjdCBkcGFhMl9xZG1hX2NvbXAgeworCWRtYV9h ZGRyX3QJCWZkX2J1c19hZGRyOworCWRtYV9hZGRyX3QJCWZsX2J1c19hZGRyOworCWRtYV9hZGRy X3QJCWRlc2NfYnVzX2FkZHI7CisJdm9pZAkJCSpmZF92aXJ0X2FkZHI7CisJdm9pZAkJCSpmbF92 aXJ0X2FkZHI7CisJdm9pZAkJCSpkZXNjX3ZpcnRfYWRkcjsKKwlzdHJ1Y3QgZHBhYTJfcWRtYV9j aGFuCSpxY2hhbjsKKwlzdHJ1Y3QgdmlydF9kbWFfZGVzYwl2ZGVzYzsKKwlzdHJ1Y3QgbGlzdF9o ZWFkCWxpc3Q7Cit9OworCitzdHJ1Y3QgZHBhYTJfcWRtYV9lbmdpbmUgeworCXN0cnVjdCBkbWFf ZGV2aWNlCWRtYV9kZXY7CisJdTMyCQkJbl9jaGFuczsKKwlzdHJ1Y3QgZHBhYTJfcWRtYV9jaGFu CWNoYW5zW05VTV9DSF07CisJaW50CQkJcWRtYV93cnR5cGVfZml4dXA7CisJaW50CQkJZGVzY19h bGxvY2F0ZWQ7CisKKwlzdHJ1Y3QgZHBhYTJfcWRtYV9wcml2ICpwcml2OworfTsKKworLyoKKyAq IGRwYWEyX3FkbWFfcHJpdiAtIGRyaXZlciBwcml2YXRlIGRhdGEKKyAqLworc3RydWN0IGRwYWEy X3FkbWFfcHJpdiB7CisJaW50IGRwcWRtYV9pZDsKKworCXN0cnVjdCBpb21tdV9kb21haW4JKmlv bW11X2RvbWFpbjsKKwlzdHJ1Y3QgZHBkbWFpX2F0dHIJZHBkbWFpX2F0dHI7CisJc3RydWN0IGRl dmljZQkJKmRldjsKKwlzdHJ1Y3QgZnNsX21jX2lvCSptY19pbzsKKwlzdHJ1Y3QgZnNsX21jX2Rl dmljZQkqZHBkbWFpX2RldjsKKwl1OAkJCW51bV9wYWlyczsKKworCXN0cnVjdCBkcGFhMl9xZG1h X2VuZ2luZQkqZHBhYTJfcWRtYTsKKwlzdHJ1Y3QgZHBhYTJfcWRtYV9wcml2X3Blcl9wcmlvCSpw cHJpdjsKKworCXN0cnVjdCBkcGRtYWlfcnhfcXVldWVfYXR0ciByeF9xdWV1ZV9hdHRyW0RQRE1B SV9QUklPX05VTV07CisJc3RydWN0IGRwZG1haV90eF9xdWV1ZV9hdHRyIHR4X3F1ZXVlX2F0dHJb RFBETUFJX1BSSU9fTlVNXTsKK307CisKK3N0cnVjdCBkcGFhMl9xZG1hX3ByaXZfcGVyX3ByaW8g eworCWludCByZXFfZnFpZDsKKwlpbnQgcnNwX2ZxaWQ7CisJaW50IHByaW87CisKKwlzdHJ1Y3Qg ZHBhYTJfaW9fc3RvcmUgKnN0b3JlOworCXN0cnVjdCBkcGFhMl9pb19ub3RpZmljYXRpb25fY3R4 IG5jdHg7CisKKwlzdHJ1Y3QgZHBhYTJfcWRtYV9wcml2ICpwcml2OworfTsKKworc3RhdGljIHN0 cnVjdCBzb2NfZGV2aWNlX2F0dHJpYnV0ZSBzb2NfZml4dXBfdHVuaW5nW10gPSB7CisJeyAuZmFt aWx5ID0gIlFvcklRIExYMjE2MEEifSwKKwl7IH0sCit9OworCisvKiBGRCBwb29sIHNpemU6IG9u ZSBGRCArIDMgRnJhbWUgbGlzdCArIDIgc291cmNlL2Rlc3RpbmF0aW9uIGRlc2NyaXB0b3IgKi8K KyNkZWZpbmUgRkRfUE9PTF9TSVpFIChzaXplb2Yoc3RydWN0IGRwYWEyX2ZkKSArIFwKKwkJc2l6 ZW9mKHN0cnVjdCBkcGFhMl9mbF9lbnRyeSkgKiAzICsgXAorCQlzaXplb2Yoc3RydWN0IGRwYWEy X3FkbWFfc2RfZCkgKiAyKQorCitzdGF0aWMgdm9pZCBkcGFhMl9kcGRtYWlfZnJlZV9jaGFubmVs cyhzdHJ1Y3QgZHBhYTJfcWRtYV9lbmdpbmUgKmRwYWEyX3FkbWEpOworc3RhdGljIHZvaWQgZHBh YTJfZHBkbWFpX2ZyZWVfY29tcChzdHJ1Y3QgZHBhYTJfcWRtYV9jaGFuICpxY2hhbiwKKwkJCQkg ICBzdHJ1Y3QgbGlzdF9oZWFkICpoZWFkKTsKKyNlbmRpZiAvKiBfX0RQQUEyX1FETUFfSCAqLwo= From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7441AC10F0E for ; Tue, 9 Apr 2019 07:29:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1F53D20880 for ; Tue, 9 Apr 2019 07:29:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726513AbfDIH3O (ORCPT ); Tue, 9 Apr 2019 03:29:14 -0400 Received: from inva020.nxp.com ([92.121.34.13]:46514 "EHLO inva020.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726464AbfDIH3O (ORCPT ); Tue, 9 Apr 2019 03:29:14 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id A943E1A018E; Tue, 9 Apr 2019 09:29:06 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 4E45A1A00DC; Tue, 9 Apr 2019 09:29:03 +0200 (CEST) Received: from titan.ap.freescale.net (TITAN.ap.freescale.net [10.192.208.233]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 310D340302; Tue, 9 Apr 2019 15:28:59 +0800 (SGT) From: Peng Ma To: vkoul@kernel.org, dan.j.williams@intel.com, leoyang.li@nxp.com Cc: linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org, Peng Ma Subject: [V3 2/2] dmaengine: fsl-dpaa2-qdma: Add NXP dpaa2 qDMA controller driver for Layerscape SoCs Date: Tue, 9 Apr 2019 15:22:12 +0800 Message-Id: <20190409072212.15860-2-peng.ma@nxp.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20190409072212.15860-1-peng.ma@nxp.com> References: <20190409072212.15860-1-peng.ma@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Sender: dmaengine-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Message-ID: <20190409072212.1_3DGrSgyi-CQNLl-MEUkSmPKiBoV3SQgLMF8SqhHv4@z> DPPA2(Data Path Acceleration Architecture 2) qDMA The qDMA supports channel virtualization by allowing DMA jobs to be enqueued into different frame queues. Core can initiate a DMA transaction by preparing a frame descriptor(FD) for each DMA job and enqueuing this job to a frame queue. through a hardware portal. The qDMA prefetches DMA jobs from the frame queues. It then schedules and dispatches to internal DMA hardware engines, which generate read and write requests. Both qDMA source data and destination data can be either contiguous or non-contiguous using one or more scatter/gather tables. The qDMA supports global bandwidth flow control where all DMA transactions are stalled if the bandwidth threshold has been reached. Also supported are transaction based read throttling. Add NXP dppa2 qDMA to support some of Layerscape SoCs. such as: LS1088A, LS208xA, LX2, etc. Signed-off-by: Peng Ma --- changed for v3: - Add depends on arm64 for dpaa2 qdma driver - The dpaa2_io_service_[de]register functions have a new parameter So update all calls to some functions drivers/dma/Kconfig | 2 + drivers/dma/Makefile | 1 + drivers/dma/fsl-dpaa2-qdma/Kconfig | 9 + drivers/dma/fsl-dpaa2-qdma/Makefile | 3 + drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c | 782 +++++++++++++++++++++++++++++++ drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.h | 152 ++++++ 6 files changed, 949 insertions(+), 0 deletions(-) create mode 100644 drivers/dma/fsl-dpaa2-qdma/Kconfig create mode 100644 drivers/dma/fsl-dpaa2-qdma/Makefile create mode 100644 drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c create mode 100644 drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.h diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index eaf78f4..08aae01 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -671,6 +671,8 @@ source "drivers/dma/sh/Kconfig" source "drivers/dma/ti/Kconfig" +source "drivers/dma/fsl-dpaa2-qdma/Kconfig" + # clients comment "DMA Clients" depends on DMA_ENGINE diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 6126e1c..2499ed8 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -75,6 +75,7 @@ obj-$(CONFIG_UNIPHIER_MDMAC) += uniphier-mdmac.o obj-$(CONFIG_XGENE_DMA) += xgene-dma.o obj-$(CONFIG_ZX_DMA) += zx_dma.o obj-$(CONFIG_ST_FDMA) += st_fdma.o +obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/ obj-y += mediatek/ obj-y += qcom/ diff --git a/drivers/dma/fsl-dpaa2-qdma/Kconfig b/drivers/dma/fsl-dpaa2-qdma/Kconfig new file mode 100644 index 0000000..258ed6b --- /dev/null +++ b/drivers/dma/fsl-dpaa2-qdma/Kconfig @@ -0,0 +1,9 @@ +menuconfig FSL_DPAA2_QDMA + tristate "NXP DPAA2 QDMA" + depends on ARM64 + depends on FSL_MC_BUS && FSL_MC_DPIO + select DMA_ENGINE + select DMA_VIRTUAL_CHANNELS + help + NXP Data Path Acceleration Architecture 2 QDMA driver, + using the NXP MC bus driver. diff --git a/drivers/dma/fsl-dpaa2-qdma/Makefile b/drivers/dma/fsl-dpaa2-qdma/Makefile new file mode 100644 index 0000000..c1d0226 --- /dev/null +++ b/drivers/dma/fsl-dpaa2-qdma/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 +# Makefile for the NXP DPAA2 qDMA controllers +obj-$(CONFIG_FSL_DPAA2_QDMA) += dpaa2-qdma.o dpdmai.o diff --git a/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c b/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c new file mode 100644 index 0000000..0cdde0f --- /dev/null +++ b/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c @@ -0,0 +1,782 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright 2014-2018 NXP + +/* + * Author: Changming Huang + * + * Driver for the NXP QDMA engine with QMan mode. + * Channel virtualization is supported through enqueuing of DMA jobs to, + * or dequeuing DMA jobs from different work queues with QMan portal. + * This module can be found on NXP LS2 SoCs. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../virt-dma.h" +#include "dpdmai_cmd.h" +#include "dpdmai.h" +#include "dpaa2-qdma.h" + +static bool smmu_disable = true; + +static struct dpaa2_qdma_chan *to_dpaa2_qdma_chan(struct dma_chan *chan) +{ + return container_of(chan, struct dpaa2_qdma_chan, vchan.chan); +} + +static struct dpaa2_qdma_comp *to_fsl_qdma_comp(struct virt_dma_desc *vd) +{ + return container_of(vd, struct dpaa2_qdma_comp, vdesc); +} + +static int dpaa2_qdma_alloc_chan_resources(struct dma_chan *chan) +{ + struct dpaa2_qdma_chan *dpaa2_chan = to_dpaa2_qdma_chan(chan); + struct dpaa2_qdma_engine *dpaa2_qdma = dpaa2_chan->qdma; + struct device *dev = &dpaa2_qdma->priv->dpdmai_dev->dev; + + dpaa2_chan->fd_pool = dma_pool_create("fd_pool", dev, + FD_POOL_SIZE, 32, 0); + if (!dpaa2_chan->fd_pool) + return -ENOMEM; + + return dpaa2_qdma->desc_allocated++; +} + +static void dpaa2_qdma_free_chan_resources(struct dma_chan *chan) +{ + struct dpaa2_qdma_chan *dpaa2_chan = to_dpaa2_qdma_chan(chan); + struct dpaa2_qdma_engine *dpaa2_qdma = dpaa2_chan->qdma; + unsigned long flags; + + LIST_HEAD(head); + + spin_lock_irqsave(&dpaa2_chan->vchan.lock, flags); + vchan_get_all_descriptors(&dpaa2_chan->vchan, &head); + spin_unlock_irqrestore(&dpaa2_chan->vchan.lock, flags); + + vchan_dma_desc_free_list(&dpaa2_chan->vchan, &head); + + dpaa2_dpdmai_free_comp(dpaa2_chan, &dpaa2_chan->comp_used); + dpaa2_dpdmai_free_comp(dpaa2_chan, &dpaa2_chan->comp_free); + + dma_pool_destroy(dpaa2_chan->fd_pool); + dpaa2_qdma->desc_allocated--; +} + +/* + * Request a command descriptor for enqueue. + */ +static struct dpaa2_qdma_comp * +dpaa2_qdma_request_desc(struct dpaa2_qdma_chan *dpaa2_chan) +{ + struct dpaa2_qdma_comp *comp_temp = NULL; + unsigned long flags; + + spin_lock_irqsave(&dpaa2_chan->queue_lock, flags); + if (list_empty(&dpaa2_chan->comp_free)) { + spin_unlock_irqrestore(&dpaa2_chan->queue_lock, flags); + comp_temp = kzalloc(sizeof(*comp_temp), GFP_KERNEL); + if (!comp_temp) + goto err; + comp_temp->fd_virt_addr = + dma_pool_alloc(dpaa2_chan->fd_pool, GFP_NOWAIT, + &comp_temp->fd_bus_addr); + if (!comp_temp->fd_virt_addr) + goto err; + + comp_temp->fl_virt_addr = + (void *)((struct dpaa2_fd *) + comp_temp->fd_virt_addr + 1); + comp_temp->fl_bus_addr = comp_temp->fd_bus_addr + + sizeof(struct dpaa2_fd); + comp_temp->desc_virt_addr = + (void *)((struct dpaa2_fl_entry *) + comp_temp->fl_virt_addr + 3); + comp_temp->desc_bus_addr = comp_temp->fl_bus_addr + + sizeof(struct dpaa2_fl_entry) * 3; + + comp_temp->qchan = dpaa2_chan; + return comp_temp; + } + comp_temp = list_first_entry(&dpaa2_chan->comp_free, + struct dpaa2_qdma_comp, list); + list_del(&comp_temp->list); + spin_unlock_irqrestore(&dpaa2_chan->queue_lock, flags); + + comp_temp->qchan = dpaa2_chan; +err: + return comp_temp; +} + +static void +dpaa2_qdma_populate_fd(u32 format, struct dpaa2_qdma_comp *dpaa2_comp) +{ + struct dpaa2_fd *fd; + + fd = (struct dpaa2_fd *)dpaa2_comp->fd_virt_addr; + memset(fd, 0, sizeof(struct dpaa2_fd)); + + /* fd populated */ + dpaa2_fd_set_addr(fd, dpaa2_comp->fl_bus_addr); + /* Bypass memory translation, Frame list format, short length disable */ + /* we need to disable BMT if fsl-mc use iova addr */ + if (smmu_disable) + dpaa2_fd_set_bpid(fd, QMAN_FD_BMT_ENABLE); + dpaa2_fd_set_format(fd, QMAN_FD_FMT_ENABLE | QMAN_FD_SL_DISABLE); + + dpaa2_fd_set_frc(fd, format | QDMA_SER_CTX); +} + +/* first frame list for descriptor buffer */ +static void +dpaa2_qdma_populate_first_framel(struct dpaa2_fl_entry *f_list, + struct dpaa2_qdma_comp *dpaa2_comp, + bool wrt_changed) +{ + struct dpaa2_qdma_sd_d *sdd; + + sdd = (struct dpaa2_qdma_sd_d *)dpaa2_comp->desc_virt_addr; + memset(sdd, 0, 2 * (sizeof(*sdd))); + + /* source descriptor CMD */ + sdd->cmd = cpu_to_le32(QDMA_SD_CMD_RDTTYPE_COHERENT); + sdd++; + + /* dest descriptor CMD */ + if (wrt_changed) + sdd->cmd = cpu_to_le32(LX2160_QDMA_DD_CMD_WRTTYPE_COHERENT); + else + sdd->cmd = cpu_to_le32(QDMA_DD_CMD_WRTTYPE_COHERENT); + + memset(f_list, 0, sizeof(struct dpaa2_fl_entry)); + + /* first frame list to source descriptor */ + dpaa2_fl_set_addr(f_list, dpaa2_comp->desc_bus_addr); + dpaa2_fl_set_len(f_list, 0x20); + dpaa2_fl_set_format(f_list, QDMA_FL_FMT_SBF | QDMA_FL_SL_LONG); + + /* bypass memory translation */ + if (smmu_disable) + f_list->bpid = cpu_to_le16(QDMA_FL_BMT_ENABLE); +} + +/* source and destination frame list */ +static void +dpaa2_qdma_populate_frames(struct dpaa2_fl_entry *f_list, + dma_addr_t dst, dma_addr_t src, + size_t len, uint8_t fmt) +{ + /* source frame list to source buffer */ + memset(f_list, 0, sizeof(struct dpaa2_fl_entry)); + + dpaa2_fl_set_addr(f_list, src); + dpaa2_fl_set_len(f_list, len); + + /* single buffer frame or scatter gather frame */ + dpaa2_fl_set_format(f_list, (fmt | QDMA_FL_SL_LONG)); + + /* bypass memory translation */ + if (smmu_disable) + f_list->bpid = cpu_to_le16(QDMA_FL_BMT_ENABLE); + + f_list++; + + /* destination frame list to destination buffer */ + memset(f_list, 0, sizeof(struct dpaa2_fl_entry)); + + dpaa2_fl_set_addr(f_list, dst); + dpaa2_fl_set_len(f_list, len); + dpaa2_fl_set_format(f_list, (fmt | QDMA_FL_SL_LONG)); + /* single buffer frame or scatter gather frame */ + dpaa2_fl_set_final(f_list, QDMA_FL_F); + /* bypass memory translation */ + if (smmu_disable) + f_list->bpid = cpu_to_le16(QDMA_FL_BMT_ENABLE); +} + +static struct dma_async_tx_descriptor +*dpaa2_qdma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, + dma_addr_t src, size_t len, ulong flags) +{ + struct dpaa2_qdma_chan *dpaa2_chan = to_dpaa2_qdma_chan(chan); + struct dpaa2_qdma_engine *dpaa2_qdma; + struct dpaa2_qdma_comp *dpaa2_comp; + struct dpaa2_fl_entry *f_list; + bool wrt_changed; + u32 format; + + dpaa2_qdma = dpaa2_chan->qdma; + dpaa2_comp = dpaa2_qdma_request_desc(dpaa2_chan); + wrt_changed = (bool)dpaa2_qdma->qdma_wrtype_fixup; + +#ifdef LONG_FORMAT + format = QDMA_FD_LONG_FORMAT; +#else + format = QDMA_FD_SHORT_FORMAT; +#endif + /* populate Frame descriptor */ + dpaa2_qdma_populate_fd(format, dpaa2_comp); + + f_list = (struct dpaa2_fl_entry *)dpaa2_comp->fl_virt_addr; + +#ifdef LONG_FORMAT + /* first frame list for descriptor buffer (logn format) */ + dpaa2_qdma_populate_first_framel(f_list, dpaa2_comp, wrt_changed); + + f_list++; +#endif + + dpaa2_qdma_populate_frames(f_list, dst, src, len, QDMA_FL_FMT_SBF); + + return vchan_tx_prep(&dpaa2_chan->vchan, &dpaa2_comp->vdesc, flags); +} + +static enum +dma_status dpaa2_qdma_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, + struct dma_tx_state *txstate) +{ + return dma_cookie_status(chan, cookie, txstate); +} + +static void dpaa2_qdma_issue_pending(struct dma_chan *chan) +{ + struct dpaa2_qdma_chan *dpaa2_chan = to_dpaa2_qdma_chan(chan); + struct dpaa2_qdma_engine *dpaa2_qdma = dpaa2_chan->qdma; + struct dpaa2_qdma_priv *priv = dpaa2_qdma->priv; + struct dpaa2_qdma_comp *dpaa2_comp; + struct virt_dma_desc *vdesc; + struct dpaa2_fd *fd; + unsigned long flags; + int err; + + spin_lock_irqsave(&dpaa2_chan->queue_lock, flags); + spin_lock(&dpaa2_chan->vchan.lock); + if (vchan_issue_pending(&dpaa2_chan->vchan)) { + vdesc = vchan_next_desc(&dpaa2_chan->vchan); + if (!vdesc) + goto err_enqueue; + dpaa2_comp = to_fsl_qdma_comp(vdesc); + + fd = (struct dpaa2_fd *)dpaa2_comp->fd_virt_addr; + + list_del(&vdesc->node); + list_add_tail(&dpaa2_comp->list, &dpaa2_chan->comp_used); + + /* TOBO: priority hard-coded to zero */ + err = dpaa2_io_service_enqueue_fq(NULL, + priv->tx_queue_attr[0].fqid, fd); + if (err) { + list_del(&dpaa2_comp->list); + list_add_tail(&dpaa2_comp->list, + &dpaa2_chan->comp_free); + } + } +err_enqueue: + spin_unlock(&dpaa2_chan->vchan.lock); + spin_unlock_irqrestore(&dpaa2_chan->queue_lock, flags); +} + +static int __cold dpaa2_qdma_setup(struct fsl_mc_device *ls_dev) +{ + struct dpaa2_qdma_priv_per_prio *ppriv; + struct device *dev = &ls_dev->dev; + struct dpaa2_qdma_priv *priv; + u8 prio_def = DPDMAI_PRIO_NUM; + int err; + int i; + + priv = dev_get_drvdata(dev); + + priv->dev = dev; + priv->dpqdma_id = ls_dev->obj_desc.id; + + /*Get the handle for the DPDMAI this interface is associate with */ + err = dpdmai_open(priv->mc_io, 0, priv->dpqdma_id, &ls_dev->mc_handle); + if (err) { + dev_err(dev, "dpdmai_open() failed\n"); + return err; + } + dev_info(dev, "Opened dpdmai object successfully\n"); + + err = dpdmai_get_attributes(priv->mc_io, 0, ls_dev->mc_handle, + &priv->dpdmai_attr); + if (err) { + dev_err(dev, "dpdmai_get_attributes() failed\n"); + return err; + } + + if (priv->dpdmai_attr.version.major > DPDMAI_VER_MAJOR) { + dev_err(dev, "DPDMAI major version mismatch\n" + "Found %u.%u, supported version is %u.%u\n", + priv->dpdmai_attr.version.major, + priv->dpdmai_attr.version.minor, + DPDMAI_VER_MAJOR, DPDMAI_VER_MINOR); + } + + if (priv->dpdmai_attr.version.minor > DPDMAI_VER_MINOR) { + dev_err(dev, "DPDMAI minor version mismatch\n" + "Found %u.%u, supported version is %u.%u\n", + priv->dpdmai_attr.version.major, + priv->dpdmai_attr.version.minor, + DPDMAI_VER_MAJOR, DPDMAI_VER_MINOR); + } + + priv->num_pairs = min(priv->dpdmai_attr.num_of_priorities, prio_def); + ppriv = kcalloc(priv->num_pairs, sizeof(*ppriv), GFP_KERNEL); + if (!ppriv) { + dev_err(dev, "kzalloc for ppriv failed\n"); + return -1; + } + priv->ppriv = ppriv; + + for (i = 0; i < priv->num_pairs; i++) { + err = dpdmai_get_rx_queue(priv->mc_io, 0, ls_dev->mc_handle, + i, &priv->rx_queue_attr[i]); + if (err) { + dev_err(dev, "dpdmai_get_rx_queue() failed\n"); + return err; + } + ppriv->rsp_fqid = priv->rx_queue_attr[i].fqid; + + err = dpdmai_get_tx_queue(priv->mc_io, 0, ls_dev->mc_handle, + i, &priv->tx_queue_attr[i]); + if (err) { + dev_err(dev, "dpdmai_get_tx_queue() failed\n"); + return err; + } + ppriv->req_fqid = priv->tx_queue_attr[i].fqid; + ppriv->prio = i; + ppriv->priv = priv; + ppriv++; + } + + return 0; +} + +static void dpaa2_qdma_fqdan_cb(struct dpaa2_io_notification_ctx *ctx) +{ + struct dpaa2_qdma_priv_per_prio *ppriv = container_of(ctx, + struct dpaa2_qdma_priv_per_prio, nctx); + struct dpaa2_qdma_comp *dpaa2_comp, *_comp_tmp; + struct dpaa2_qdma_priv *priv = ppriv->priv; + u32 n_chans = priv->dpaa2_qdma->n_chans; + struct dpaa2_qdma_chan *qchan; + const struct dpaa2_fd *fd_eq; + const struct dpaa2_fd *fd; + struct dpaa2_dq *dq; + int is_last = 0; + int found; + u8 status; + int err; + int i; + + do { + err = dpaa2_io_service_pull_fq(NULL, ppriv->rsp_fqid, + ppriv->store); + } while (err); + + while (!is_last) { + do { + dq = dpaa2_io_store_next(ppriv->store, &is_last); + } while (!is_last && !dq); + if (!dq) { + dev_err(priv->dev, "FQID returned no valid frames!\n"); + continue; + } + + /* obtain FD and process the error */ + fd = dpaa2_dq_fd(dq); + + status = dpaa2_fd_get_ctrl(fd) & 0xff; + if (status) + dev_err(priv->dev, "FD error occurred\n"); + found = 0; + for (i = 0; i < n_chans; i++) { + qchan = &priv->dpaa2_qdma->chans[i]; + spin_lock(&qchan->queue_lock); + if (list_empty(&qchan->comp_used)) { + spin_unlock(&qchan->queue_lock); + continue; + } + list_for_each_entry_safe(dpaa2_comp, _comp_tmp, + &qchan->comp_used, list) { + fd_eq = (struct dpaa2_fd *) + dpaa2_comp->fd_virt_addr; + + if (le64_to_cpu(fd_eq->simple.addr) == + le64_to_cpu(fd->simple.addr)) { + spin_lock(&qchan->vchan.lock); + vchan_cookie_complete(& + dpaa2_comp->vdesc); + spin_unlock(&qchan->vchan.lock); + found = 1; + break; + } + } + spin_unlock(&qchan->queue_lock); + if (found) + break; + } + } + + dpaa2_io_service_rearm(NULL, ctx); +} + +static int __cold dpaa2_qdma_dpio_setup(struct dpaa2_qdma_priv *priv) +{ + struct dpaa2_qdma_priv_per_prio *ppriv; + struct device *dev = priv->dev; + int err, i, num; + + num = priv->num_pairs; + ppriv = priv->ppriv; + for (i = 0; i < num; i++) { + ppriv->nctx.is_cdan = 0; + ppriv->nctx.desired_cpu = 1; + ppriv->nctx.id = ppriv->rsp_fqid; + ppriv->nctx.cb = dpaa2_qdma_fqdan_cb; + err = dpaa2_io_service_register(NULL, &ppriv->nctx, dev); + if (err) { + dev_err(dev, "Notification register failed\n"); + goto err_service; + } + + ppriv->store = + dpaa2_io_store_create(DPAA2_QDMA_STORE_SIZE, dev); + if (!ppriv->store) { + dev_err(dev, "dpaa2_io_store_create() failed\n"); + goto err_store; + } + + ppriv++; + } + return 0; + +err_store: + dpaa2_io_service_deregister(NULL, &ppriv->nctx, dev); +err_service: + ppriv--; + while (ppriv >= priv->ppriv) { + dpaa2_io_service_deregister(NULL, &ppriv->nctx, dev); + dpaa2_io_store_destroy(ppriv->store); + ppriv--; + } + return -1; +} + +static void dpaa2_dpmai_store_free(struct dpaa2_qdma_priv *priv) +{ + struct dpaa2_qdma_priv_per_prio *ppriv = priv->ppriv; + int i; + + for (i = 0; i < priv->num_pairs; i++) { + dpaa2_io_store_destroy(ppriv->store); + ppriv++; + } +} + +static void dpaa2_dpdmai_dpio_free(struct dpaa2_qdma_priv *priv) +{ + struct dpaa2_qdma_priv_per_prio *ppriv = priv->ppriv; + struct device *dev = priv->dev; + int i; + + for (i = 0; i < priv->num_pairs; i++) { + dpaa2_io_service_deregister(NULL, &ppriv->nctx, dev); + ppriv++; + } +} + +static int __cold dpaa2_dpdmai_bind(struct dpaa2_qdma_priv *priv) +{ + int err; + int i, num; + struct device *dev = priv->dev; + struct dpaa2_qdma_priv_per_prio *ppriv; + struct dpdmai_rx_queue_cfg rx_queue_cfg; + struct fsl_mc_device *ls_dev = to_fsl_mc_device(dev); + + num = priv->num_pairs; + ppriv = priv->ppriv; + for (i = 0; i < num; i++) { + rx_queue_cfg.options = DPDMAI_QUEUE_OPT_USER_CTX | + DPDMAI_QUEUE_OPT_DEST; + rx_queue_cfg.user_ctx = ppriv->nctx.qman64; + rx_queue_cfg.dest_cfg.dest_type = DPDMAI_DEST_DPIO; + rx_queue_cfg.dest_cfg.dest_id = ppriv->nctx.dpio_id; + rx_queue_cfg.dest_cfg.priority = ppriv->prio; + err = dpdmai_set_rx_queue(priv->mc_io, 0, ls_dev->mc_handle, + rx_queue_cfg.dest_cfg.priority, + &rx_queue_cfg); + if (err) { + dev_err(dev, "dpdmai_set_rx_queue() failed\n"); + return err; + } + + ppriv++; + } + + return 0; +} + +static int __cold dpaa2_dpdmai_dpio_unbind(struct dpaa2_qdma_priv *priv) +{ + int i; + int err = 0; + struct device *dev = priv->dev; + struct fsl_mc_device *ls_dev = to_fsl_mc_device(dev); + struct dpaa2_qdma_priv_per_prio *ppriv = priv->ppriv; + + for (i = 0; i < priv->num_pairs; i++) { + ppriv->nctx.qman64 = 0; + ppriv->nctx.dpio_id = 0; + ppriv++; + } + + err = dpdmai_reset(priv->mc_io, 0, ls_dev->mc_handle); + if (err) + dev_err(dev, "dpdmai_reset() failed\n"); + + return err; +} + +static void dpaa2_dpdmai_free_comp(struct dpaa2_qdma_chan *qchan, + struct list_head *head) +{ + struct dpaa2_qdma_comp *comp_tmp, *_comp_tmp; + + list_for_each_entry_safe(comp_tmp, _comp_tmp, + head, list) { + dma_pool_free(qchan->fd_pool, + comp_tmp->fd_virt_addr, + comp_tmp->fd_bus_addr); + list_del(&comp_tmp->list); + kfree(comp_tmp); + } +} + +static void dpaa2_dpdmai_free_channels(struct dpaa2_qdma_engine *dpaa2_qdma) +{ + struct dpaa2_qdma_chan *qchan; + int num, i; + + num = dpaa2_qdma->n_chans; + for (i = 0; i < num; i++) { + qchan = &dpaa2_qdma->chans[i]; + dpaa2_dpdmai_free_comp(qchan, &qchan->comp_used); + dpaa2_dpdmai_free_comp(qchan, &qchan->comp_free); + dma_pool_destroy(qchan->fd_pool); + } +} + +static void dpaa2_qdma_free_desc(struct virt_dma_desc *vdesc) +{ + struct dpaa2_qdma_comp *dpaa2_comp; + struct dpaa2_qdma_chan *qchan; + + dpaa2_comp = to_fsl_qdma_comp(vdesc); + qchan = dpaa2_comp->qchan; + list_del(&dpaa2_comp->list); + list_add_tail(&dpaa2_comp->list, &qchan->comp_free); +} + +static int dpaa2_dpdmai_init_channels(struct dpaa2_qdma_engine *dpaa2_qdma) +{ + struct dpaa2_qdma_chan *dpaa2_chan; + int i; + + INIT_LIST_HEAD(&dpaa2_qdma->dma_dev.channels); + for (i = 0; i < dpaa2_qdma->n_chans; i++) { + dpaa2_chan = &dpaa2_qdma->chans[i]; + dpaa2_chan->qdma = dpaa2_qdma; + dpaa2_chan->vchan.desc_free = dpaa2_qdma_free_desc; + vchan_init(&dpaa2_chan->vchan, &dpaa2_qdma->dma_dev); + spin_lock_init(&dpaa2_chan->queue_lock); + INIT_LIST_HEAD(&dpaa2_chan->comp_used); + INIT_LIST_HEAD(&dpaa2_chan->comp_free); + } + return 0; +} + +static int dpaa2_qdma_probe(struct fsl_mc_device *dpdmai_dev) +{ + struct dpaa2_qdma_priv *priv; + struct device *dev = &dpdmai_dev->dev; + struct dpaa2_qdma_engine *dpaa2_qdma; + int err; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + dev_set_drvdata(dev, priv); + priv->dpdmai_dev = dpdmai_dev; + + priv->iommu_domain = iommu_get_domain_for_dev(dev); + if (priv->iommu_domain) + smmu_disable = false; + + /* obtain a MC portal */ + err = fsl_mc_portal_allocate(dpdmai_dev, 0, &priv->mc_io); + if (err) { + if (err == -ENXIO) + err = -EPROBE_DEFER; + else + dev_err(dev, "MC portal allocation failed\n"); + goto err_mcportal; + } + + /* DPDMAI initialization */ + err = dpaa2_qdma_setup(dpdmai_dev); + if (err) { + dev_err(dev, "dpaa2_dpdmai_setup() failed\n"); + goto err_dpdmai_setup; + } + + /* DPIO */ + err = dpaa2_qdma_dpio_setup(priv); + if (err) { + dev_err(dev, "dpaa2_dpdmai_dpio_setup() failed\n"); + goto err_dpio_setup; + } + + /* DPDMAI binding to DPIO */ + err = dpaa2_dpdmai_bind(priv); + if (err) { + dev_err(dev, "dpaa2_dpdmai_bind() failed\n"); + goto err_bind; + } + + /* DPDMAI enable */ + err = dpdmai_enable(priv->mc_io, 0, dpdmai_dev->mc_handle); + if (err) { + dev_err(dev, "dpdmai_enable() faile\n"); + goto err_enable; + } + + dpaa2_qdma = kzalloc(sizeof(*dpaa2_qdma), GFP_KERNEL); + if (!dpaa2_qdma) { + err = -ENOMEM; + goto err_eng; + } + + priv->dpaa2_qdma = dpaa2_qdma; + dpaa2_qdma->priv = priv; + + dpaa2_qdma->desc_allocated = 0; + dpaa2_qdma->n_chans = NUM_CH; + + dpaa2_dpdmai_init_channels(dpaa2_qdma); + + if (soc_device_match(soc_fixup_tuning)) + dpaa2_qdma->qdma_wrtype_fixup = true; + else + dpaa2_qdma->qdma_wrtype_fixup = false; + + dma_cap_set(DMA_PRIVATE, dpaa2_qdma->dma_dev.cap_mask); + dma_cap_set(DMA_SLAVE, dpaa2_qdma->dma_dev.cap_mask); + dma_cap_set(DMA_MEMCPY, dpaa2_qdma->dma_dev.cap_mask); + + dpaa2_qdma->dma_dev.dev = dev; + dpaa2_qdma->dma_dev.device_alloc_chan_resources = + dpaa2_qdma_alloc_chan_resources; + dpaa2_qdma->dma_dev.device_free_chan_resources = + dpaa2_qdma_free_chan_resources; + dpaa2_qdma->dma_dev.device_tx_status = dpaa2_qdma_tx_status; + dpaa2_qdma->dma_dev.device_prep_dma_memcpy = dpaa2_qdma_prep_memcpy; + dpaa2_qdma->dma_dev.device_issue_pending = dpaa2_qdma_issue_pending; + + err = dma_async_device_register(&dpaa2_qdma->dma_dev); + if (err) { + dev_err(dev, "Can't register NXP QDMA engine.\n"); + goto err_eng; + } + + return 0; + +err_eng: + dpdmai_disable(priv->mc_io, 0, dpdmai_dev->mc_handle); +err_enable: + dpaa2_dpdmai_dpio_unbind(priv); +err_bind: + dpaa2_dpmai_store_free(priv); + dpaa2_dpdmai_dpio_free(priv); +err_dpio_setup: + dpdmai_close(priv->mc_io, 0, dpdmai_dev->mc_handle); +err_dpdmai_setup: + fsl_mc_portal_free(priv->mc_io); +err_mcportal: + kfree(priv->ppriv); + kfree(priv); + dev_set_drvdata(dev, NULL); + return err; +} + +static int dpaa2_qdma_remove(struct fsl_mc_device *ls_dev) +{ + struct device *dev; + struct dpaa2_qdma_priv *priv; + struct dpaa2_qdma_engine *dpaa2_qdma; + + dev = &ls_dev->dev; + priv = dev_get_drvdata(dev); + dpaa2_qdma = priv->dpaa2_qdma; + + dpdmai_disable(priv->mc_io, 0, ls_dev->mc_handle); + dpaa2_dpdmai_dpio_unbind(priv); + dpaa2_dpmai_store_free(priv); + dpaa2_dpdmai_dpio_free(priv); + dpdmai_close(priv->mc_io, 0, ls_dev->mc_handle); + fsl_mc_portal_free(priv->mc_io); + dev_set_drvdata(dev, NULL); + dpaa2_dpdmai_free_channels(dpaa2_qdma); + + dma_async_device_unregister(&dpaa2_qdma->dma_dev); + kfree(priv); + kfree(dpaa2_qdma); + + return 0; +} + +static const struct fsl_mc_device_id dpaa2_qdma_id_table[] = { + { + .vendor = FSL_MC_VENDOR_FREESCALE, + .obj_type = "dpdmai", + }, + { .vendor = 0x0 } +}; + +static struct fsl_mc_driver dpaa2_qdma_driver = { + .driver = { + .name = "dpaa2-qdma", + .owner = THIS_MODULE, + }, + .probe = dpaa2_qdma_probe, + .remove = dpaa2_qdma_remove, + .match_id_table = dpaa2_qdma_id_table +}; + +static int __init dpaa2_qdma_driver_init(void) +{ + return fsl_mc_driver_register(&(dpaa2_qdma_driver)); +} +late_initcall(dpaa2_qdma_driver_init); + +static void __exit fsl_qdma_exit(void) +{ + fsl_mc_driver_unregister(&(dpaa2_qdma_driver)); +} +module_exit(fsl_qdma_exit); + +MODULE_ALIAS("platform:fsl-dpaa2-qdma"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("NXP Layerscape DPAA2 qDMA engine driver"); diff --git a/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.h b/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.h new file mode 100644 index 0000000..3fcade8 --- /dev/null +++ b/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.h @@ -0,0 +1,152 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright 2014-2018 NXP */ + +#ifndef __DPAA2_QDMA_H +#define __DPAA2_QDMA_H + +#define LONG_FORMAT 1 + +#define DPAA2_QDMA_STORE_SIZE 16 +#define NUM_CH 8 + +struct dpaa2_qdma_sd_d { + u32 rsv:32; + union { + struct { + u32 ssd:12; /* souce stride distance */ + u32 sss:12; /* souce stride size */ + u32 rsv1:8; + } sdf; + struct { + u32 dsd:12; /* Destination stride distance */ + u32 dss:12; /* Destination stride size */ + u32 rsv2:8; + } ddf; + } df; + u32 rbpcmd; /* Route-by-port command */ + u32 cmd; +} __attribute__((__packed__)); + +/* Source descriptor command read transaction type for RBP=0: */ +/* coherent copy of cacheable memory */ +#define QDMA_SD_CMD_RDTTYPE_COHERENT (0xb << 28) +/* Destination descriptor command write transaction type for RBP=0: */ +/* coherent copy of cacheable memory */ +#define QDMA_DD_CMD_WRTTYPE_COHERENT (0x6 << 28) +#define LX2160_QDMA_DD_CMD_WRTTYPE_COHERENT (0xb << 28) + +#define QMAN_FD_FMT_ENABLE BIT(0) /* frame list table enable */ +#define QMAN_FD_BMT_ENABLE BIT(15) /* bypass memory translation */ +#define QMAN_FD_BMT_DISABLE (0) /* bypass memory translation */ +#define QMAN_FD_SL_DISABLE (0) /* short lengthe disabled */ +#define QMAN_FD_SL_ENABLE BIT(14) /* short lengthe enabled */ + +#define QDMA_FINAL_BIT_DISABLE (0) /* final bit disable */ +#define QDMA_FINAL_BIT_ENABLE BIT(31) /* final bit enable */ + +#define QDMA_FD_SHORT_FORMAT BIT(11) /* short format */ +#define QDMA_FD_LONG_FORMAT (0) /* long format */ +#define QDMA_SER_DISABLE (8) /* no notification */ +#define QDMA_SER_CTX BIT(8) /* notification by FQD_CTX[fqid] */ +#define QDMA_SER_DEST (2 << 8) /* notification by destination desc */ +#define QDMA_SER_BOTH (3 << 8) /* soruce and dest notification */ +#define QDMA_FD_SPF_ENALBE BIT(30) /* source prefetch enable */ + +#define QMAN_FD_VA_ENABLE BIT(14) /* Address used is virtual address */ +#define QMAN_FD_VA_DISABLE (0)/* Address used is a real address */ +/* Flow Context: 49bit physical address */ +#define QMAN_FD_CBMT_ENABLE BIT(15) +#define QMAN_FD_CBMT_DISABLE (0) /* Flow Context: 64bit virtual address */ +#define QMAN_FD_SC_DISABLE (0) /* stashing control */ + +#define QDMA_FL_FMT_SBF (0x0) /* Single buffer frame */ +#define QDMA_FL_FMT_SGE (0x2) /* Scatter gather frame */ +#define QDMA_FL_BMT_ENABLE BIT(15) /* enable bypass memory translation */ +#define QDMA_FL_BMT_DISABLE (0x0) /* enable bypass memory translation */ +#define QDMA_FL_SL_LONG (0x0)/* long length */ +#define QDMA_FL_SL_SHORT (0x1) /* short length */ +#define QDMA_FL_F (0x1)/* last frame list bit */ + +/*Description of Frame list table structure*/ +struct dpaa2_qdma_chan { + struct virt_dma_chan vchan; + struct virt_dma_desc vdesc; + enum dma_status status; + struct dpaa2_qdma_engine *qdma; + + struct mutex dpaa2_queue_mutex; + spinlock_t queue_lock; + struct dma_pool *fd_pool; + + struct list_head comp_used; + struct list_head comp_free; + +}; + +struct dpaa2_qdma_comp { + dma_addr_t fd_bus_addr; + dma_addr_t fl_bus_addr; + dma_addr_t desc_bus_addr; + void *fd_virt_addr; + void *fl_virt_addr; + void *desc_virt_addr; + struct dpaa2_qdma_chan *qchan; + struct virt_dma_desc vdesc; + struct list_head list; +}; + +struct dpaa2_qdma_engine { + struct dma_device dma_dev; + u32 n_chans; + struct dpaa2_qdma_chan chans[NUM_CH]; + int qdma_wrtype_fixup; + int desc_allocated; + + struct dpaa2_qdma_priv *priv; +}; + +/* + * dpaa2_qdma_priv - driver private data + */ +struct dpaa2_qdma_priv { + int dpqdma_id; + + struct iommu_domain *iommu_domain; + struct dpdmai_attr dpdmai_attr; + struct device *dev; + struct fsl_mc_io *mc_io; + struct fsl_mc_device *dpdmai_dev; + u8 num_pairs; + + struct dpaa2_qdma_engine *dpaa2_qdma; + struct dpaa2_qdma_priv_per_prio *ppriv; + + struct dpdmai_rx_queue_attr rx_queue_attr[DPDMAI_PRIO_NUM]; + struct dpdmai_tx_queue_attr tx_queue_attr[DPDMAI_PRIO_NUM]; +}; + +struct dpaa2_qdma_priv_per_prio { + int req_fqid; + int rsp_fqid; + int prio; + + struct dpaa2_io_store *store; + struct dpaa2_io_notification_ctx nctx; + + struct dpaa2_qdma_priv *priv; +}; + +static struct soc_device_attribute soc_fixup_tuning[] = { + { .family = "QorIQ LX2160A"}, + { }, +}; + +/* FD pool size: one FD + 3 Frame list + 2 source/destination descriptor */ +#define FD_POOL_SIZE (sizeof(struct dpaa2_fd) + \ + sizeof(struct dpaa2_fl_entry) * 3 + \ + sizeof(struct dpaa2_qdma_sd_d) * 2) + +static void dpaa2_dpdmai_free_channels(struct dpaa2_qdma_engine *dpaa2_qdma); +static void dpaa2_dpdmai_free_comp(struct dpaa2_qdma_chan *qchan, + struct list_head *head); +#endif /* __DPAA2_QDMA_H */ -- 1.7.1