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.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, MIME_BASE64_TEXT,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, 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 10CC6C433E1 for ; Thu, 9 Jul 2020 09:12:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D67B7207FC for ; Thu, 9 Jul 2020 09:12:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="Cb85n6SR" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726707AbgGIJMi (ORCPT ); Thu, 9 Jul 2020 05:12:38 -0400 Received: from mailgw01.mediatek.com ([210.61.82.183]:21191 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1726645AbgGIJMh (ORCPT ); Thu, 9 Jul 2020 05:12:37 -0400 X-UUID: 00b0cf0c18be46b1a1254038fcd68468-20200709 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=uEIodGb+H0SrBqh8VNgfTXkSpyd8DbLFMTrEpDE4eVA=; b=Cb85n6SRfM7l5AP9Kod9cb4gFsFaQaQQk+7QKqmUkVd/txieafbi6bgT+wLNSWO05k4UB5YXGGRaY0eczPcvdYH3C09Te/DQodM2Nx2oq6AQxkPBexoMPyVjCD+yjyMyuuO/N6I9LCuprPNh1xTL+LUwIN1srLq0z0da6+hPy3c=; X-UUID: 00b0cf0c18be46b1a1254038fcd68468-20200709 Received: from mtkcas10.mediatek.inc [(172.21.101.39)] by mailgw01.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 1822507380; Thu, 09 Jul 2020 17:12:26 +0800 Received: from mtkcas08.mediatek.inc (172.21.101.126) by mtkmbs01n1.mediatek.inc (172.21.101.68) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 9 Jul 2020 17:12:16 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas08.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 9 Jul 2020 17:12:18 +0800 From: Neal Liu To: Rob Herring , Matthias Brugger CC: Neal Liu , , , , lkml , Subject: [PATCH v2 2/2] soc: mediatek: add mtk-devapc driver Date: Thu, 9 Jul 2020 17:12:07 +0800 Message-ID: <1594285927-1840-3-git-send-email-neal.liu@mediatek.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1594285927-1840-1-git-send-email-neal.liu@mediatek.com> References: <1594285927-1840-1-git-send-email-neal.liu@mediatek.com> MIME-Version: 1.0 Content-Type: text/plain X-MTK: N Content-Transfer-Encoding: base64 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org TWVkaWFUZWsgYnVzIGZhYnJpYyBwcm92aWRlcyBUcnVzdFpvbmUgc2VjdXJpdHkgc3VwcG9ydCBh bmQgZGF0YQ0KcHJvdGVjdGlvbiB0byBwcmV2ZW50IHNsYXZlcyBmcm9tIGJlaW5nIGFjY2Vzc2Vk IGJ5IHVuZXhwZWN0ZWQNCm1hc3RlcnMuDQpUaGUgc2VjdXJpdHkgdmlvbGF0aW9uIGlzIGxvZ2dl ZCBhbmQgc2VudCB0byB0aGUgcHJvY2Vzc29yIGZvcg0KZnVydGhlciBhbmFseXNpcyBvciBjb3Vu dGVybWVhc3VyZXMuDQoNCkFueSBvY2N1cnJlbmNlIG9mIHNlY3VyaXR5IHZpb2xhdGlvbiB3b3Vs ZCByYWlzZSBhbiBpbnRlcnJ1cHQsIGFuZA0KaXQgd2lsbCBiZSBoYW5kbGVkIGJ5IG10ay1kZXZh cGMgZHJpdmVyLiBUaGUgdmlvbGF0aW9uDQppbmZvcm1hdGlvbiBpcyBwcmludGVkIGluIG9yZGVy IHRvIGZpbmQgdGhlIG11cmRlcmVyLg0KDQpTaWduZWQtb2ZmLWJ5OiBOZWFsIExpdSA8bmVhbC5s aXVAbWVkaWF0ZWsuY29tPg0KLS0tDQogZHJpdmVycy9zb2MvbWVkaWF0ZWsvS2NvbmZpZyAgICAg IHwgICAgOSArDQogZHJpdmVycy9zb2MvbWVkaWF0ZWsvTWFrZWZpbGUgICAgIHwgICAgMSArDQog ZHJpdmVycy9zb2MvbWVkaWF0ZWsvbXRrLWRldmFwYy5jIHwgIDQ2NiArKysrKysrKysrKysrKysr KysrKysrKysrKw0KIGRyaXZlcnMvc29jL21lZGlhdGVrL210ay1kZXZhcGMuaCB8ICA2NzAgKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKw0KIDQgZmlsZXMgY2hhbmdlZCwgMTE0 NiBpbnNlcnRpb25zKCspDQogY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvc29jL21lZGlhdGVr L210ay1kZXZhcGMuYw0KIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL3NvYy9tZWRpYXRlay9t dGstZGV2YXBjLmgNCg0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvc29jL21lZGlhdGVrL0tjb25maWcg Yi9kcml2ZXJzL3NvYy9tZWRpYXRlay9LY29uZmlnDQppbmRleCA1OWE1NmNkLi4xMTc3Yzk4IDEw MDY0NA0KLS0tIGEvZHJpdmVycy9zb2MvbWVkaWF0ZWsvS2NvbmZpZw0KKysrIGIvZHJpdmVycy9z b2MvbWVkaWF0ZWsvS2NvbmZpZw0KQEAgLTE3LDYgKzE3LDE1IEBAIGNvbmZpZyBNVEtfQ01EUQ0K IAkgIHRpbWUgbGltaXRhdGlvbiwgc3VjaCBhcyB1cGRhdGluZyBkaXNwbGF5IGNvbmZpZ3VyYXRp b24gZHVyaW5nIHRoZQ0KIAkgIHZibGFuay4NCiANCitjb25maWcgTVRLX0RFVkFQQw0KKwl0cmlz dGF0ZSAiTWVkaWF0ZWsgRGV2aWNlIEFQQyBTdXBwb3J0Ig0KKwloZWxwDQorCSAgU2F5IHllcyBo ZXJlIHRvIGVuYWJsZSBzdXBwb3J0IGZvciBNZWRpYXRlayBEZXZpY2UgQVBDIGRyaXZlci4NCisJ ICBUaGlzIGRyaXZlciBpcyBtYWlubHkgdXNlZCB0byBoYW5kbGUgdGhlIHZpb2xhdGlvbiB3aGlj aCBjYXRjaGVzDQorCSAgdW5leHBlY3RlZCB0cmFuc2FjdGlvbi4NCisJICBUaGUgdmlvbGF0aW9u IGluZm9ybWF0aW9uIGlzIGxvZ2dlZCBmb3IgZnVydGhlciBhbmFseXNpcyBvcg0KKwkgIGNvdW50 ZXJtZWFzdXJlcy4NCisNCiBjb25maWcgTVRLX0lORlJBQ0ZHDQogCWJvb2wgIk1lZGlhVGVrIElO RlJBQ0ZHIFN1cHBvcnQiDQogCXNlbGVjdCBSRUdNQVANCmRpZmYgLS1naXQgYS9kcml2ZXJzL3Nv Yy9tZWRpYXRlay9NYWtlZmlsZSBiL2RyaXZlcnMvc29jL21lZGlhdGVrL01ha2VmaWxlDQppbmRl eCAwMWY5Zjg3Li5hYmZkNGJhIDEwMDY0NA0KLS0tIGEvZHJpdmVycy9zb2MvbWVkaWF0ZWsvTWFr ZWZpbGUNCisrKyBiL2RyaXZlcnMvc29jL21lZGlhdGVrL01ha2VmaWxlDQpAQCAtMSw1ICsxLDYg QEANCiAjIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wLW9ubHkNCiBvYmotJChDT05G SUdfTVRLX0NNRFEpICs9IG10ay1jbWRxLWhlbHBlci5vDQorb2JqLSQoQ09ORklHX01US19ERVZB UEMpICs9IG10ay1kZXZhcGMubw0KIG9iai0kKENPTkZJR19NVEtfSU5GUkFDRkcpICs9IG10ay1p bmZyYWNmZy5vDQogb2JqLSQoQ09ORklHX01US19QTUlDX1dSQVApICs9IG10ay1wbWljLXdyYXAu bw0KIG9iai0kKENPTkZJR19NVEtfU0NQU1lTKSArPSBtdGstc2Nwc3lzLm8NCmRpZmYgLS1naXQg YS9kcml2ZXJzL3NvYy9tZWRpYXRlay9tdGstZGV2YXBjLmMgYi9kcml2ZXJzL3NvYy9tZWRpYXRl ay9tdGstZGV2YXBjLmMNCm5ldyBmaWxlIG1vZGUgMTAwNjQ0DQppbmRleCAwMDAwMDAwLi4xMWZh MzY2DQotLS0gL2Rldi9udWxsDQorKysgYi9kcml2ZXJzL3NvYy9tZWRpYXRlay9tdGstZGV2YXBj LmMNCkBAIC0wLDAgKzEsNDY2IEBADQorLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0y LjANCisvKg0KKyAqIENvcHlyaWdodCAoQykgMjAyMCBNZWRpYVRlayBJbmMuDQorICovDQorDQor I2luY2x1ZGUgPGxpbnV4L2Nsay5oPg0KKyNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4NCisj aW5jbHVkZSA8bGludXgvbW9kdWxlLmg+DQorI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2Rldmlj ZS5oPg0KKyNpbmNsdWRlIDxsaW51eC9vZl9pcnEuaD4NCisjaW5jbHVkZSA8bGludXgvb2ZfYWRk cmVzcy5oPg0KKyNpbmNsdWRlICJtdGstZGV2YXBjLmgiDQorDQorLyoNCisgKiBtdGtfZGV2YXBj X3BkX2dldCAtIGdldCBkZXZhcGMgcGRfdHlwZXMgb2YgcmVnaXN0ZXIgYWRkcmVzcy4NCisgKg0K KyAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHJlZyBhZGRyDQorICovDQorc3RhdGljIHZvaWQgX19p b21lbSAqbXRrX2RldmFwY19wZF9nZXQoc3RydWN0IG10a19kZXZhcGNfY29udGV4dCAqZGV2YXBj X2N0eCwNCisJCQkJICAgICAgIGludCBzbGF2ZV90eXBlLA0KKwkJCQkgICAgICAgZW51bSBERVZB UENfUERfUkVHX1RZUEUgcGRfcmVnX3R5cGUsDQorCQkJCSAgICAgICB1MzIgcmVnX2lkeCkNCit7 DQorCXZvaWQgX19pb21lbSAqcmVnOw0KKw0KKwlyZWcgPSBkZXZhcGNfY3R4LT5kZXZhcGNfcGRf YmFzZVtzbGF2ZV90eXBlXSArDQorCQlkZXZhcGNfY3R4LT5wZHNfb2Zmc2V0W3BkX3JlZ190eXBl XTsNCisNCisJaWYgKHBkX3JlZ190eXBlID09IFZJT19NQVNLIHx8IHBkX3JlZ190eXBlID09IFZJ T19TVEEpDQorCQlyZWcgKz0gMHg0ICogcmVnX2lkeDsNCisNCisJcmV0dXJuIHJlZzsNCit9DQor DQorc3RhdGljIGludCBnZXRfdmlvX3NsYXZlX251bShpbnQgc2xhdmVfdHlwZSkNCit7DQorCWlm IChzbGF2ZV90eXBlID09IDApDQorCQlyZXR1cm4gQVJSQVlfU0laRShtdGtfZGV2aWNlc19pbmZy YSk7DQorDQorCXJldHVybiAwOw0KK30NCisNCitzdGF0aWMgdTMyIGdldF9zaGlmdF9ncm91cChz dHJ1Y3QgbXRrX2RldmFwY19jb250ZXh0ICpkZXZhcGNfY3R4LA0KKwkJCSAgIGludCBzbGF2ZV90 eXBlLCBpbnQgdmlvX2lkeCkNCit7DQorCXUzMiB2aW9fc2hpZnRfc3RhOw0KKwl2b2lkIF9faW9t ZW0gKnJlZzsNCisJaW50IGJpdDsNCisNCisJcmVnID0gbXRrX2RldmFwY19wZF9nZXQoZGV2YXBj X2N0eCwgc2xhdmVfdHlwZSwgVklPX1NISUZUX1NUQSwgMCk7DQorCXZpb19zaGlmdF9zdGEgPSBy ZWFkbChyZWcpOw0KKw0KKwlmb3IgKGJpdCA9IDA7IGJpdCA8IDMyOyBiaXQrKykgew0KKwkJaWYg KCh2aW9fc2hpZnRfc3RhID4+IGJpdCkgJiAweDEpDQorCQkJYnJlYWs7DQorCX0NCisNCisJcmV0 dXJuIGJpdDsNCit9DQorDQorc3RhdGljIGludCBjaGVja192aW9fbWFza19zdGEoc3RydWN0IG10 a19kZXZhcGNfY29udGV4dCAqZGV2YXBjX2N0eCwNCisJCQkgICAgICBpbnQgc2xhdmVfdHlwZSwg dTMyIG1vZHVsZSwgaW50IHBkX3JlZ190eXBlKQ0KK3sNCisJdTMyIHJlZ19pbmRleCwgcmVnX29m ZnNldDsNCisJdm9pZCBfX2lvbWVtICpyZWc7DQorCXUzMiB2YWx1ZTsNCisNCisJVklPX01BU0tf U1RBX1JFR19HRVQobW9kdWxlKTsNCisNCisJcmVnID0gbXRrX2RldmFwY19wZF9nZXQoZGV2YXBj X2N0eCwgc2xhdmVfdHlwZSwgcGRfcmVnX3R5cGUsIHJlZ19pbmRleCk7DQorCXZhbHVlID0gcmVh ZGwocmVnKTsNCisNCisJcmV0dXJuICgodmFsdWUgPj4gcmVnX29mZnNldCkgJiAweDEpOw0KK30N CisNCitzdGF0aWMgaW50IGNoZWNrX3Zpb19tYXNrKHN0cnVjdCBtdGtfZGV2YXBjX2NvbnRleHQg KmRldmFwY19jdHgsIGludCBzbGF2ZV90eXBlLA0KKwkJCSAgdTMyIG1vZHVsZSkNCit7DQorCXJl dHVybiBjaGVja192aW9fbWFza19zdGEoZGV2YXBjX2N0eCwgc2xhdmVfdHlwZSwgbW9kdWxlLCBW SU9fTUFTSyk7DQorfQ0KKw0KK3N0YXRpYyBpbnQgY2hlY2tfdmlvX3N0YXR1cyhzdHJ1Y3QgbXRr X2RldmFwY19jb250ZXh0ICpkZXZhcGNfY3R4LA0KKwkJCSAgICBpbnQgc2xhdmVfdHlwZSwgdTMy IG1vZHVsZSkNCit7DQorCXJldHVybiBjaGVja192aW9fbWFza19zdGEoZGV2YXBjX2N0eCwgc2xh dmVfdHlwZSwgbW9kdWxlLCBWSU9fU1RBKTsNCit9DQorDQorc3RhdGljIHZvaWQgY2xlYXJfdmlv X3N0YXR1cyhzdHJ1Y3QgbXRrX2RldmFwY19jb250ZXh0ICpkZXZhcGNfY3R4LA0KKwkJCSAgICAg aW50IHNsYXZlX3R5cGUsIHUzMiBtb2R1bGUpDQorew0KKwl1MzIgcmVnX2luZGV4LCByZWdfb2Zm c2V0Ow0KKwl2b2lkIF9faW9tZW0gKnJlZzsNCisNCisJVklPX01BU0tfU1RBX1JFR19HRVQobW9k dWxlKTsNCisNCisJcmVnID0gbXRrX2RldmFwY19wZF9nZXQoZGV2YXBjX2N0eCwgc2xhdmVfdHlw ZSwgVklPX1NUQSwgcmVnX2luZGV4KTsNCisJd3JpdGVsKDB4MSA8PCByZWdfb2Zmc2V0LCByZWcp Ow0KKw0KKwlpZiAoY2hlY2tfdmlvX3N0YXR1cyhkZXZhcGNfY3R4LCBzbGF2ZV90eXBlLCBtb2R1 bGUpKQ0KKwkJcHJfZXJyKFBGWCAiJXM6IENsZWFyIGZhaWxlZCwgc2xhdmVfdHlwZToweCV4LCBt b2R1bGVfaW5kZXg6MHgleFxuIiwNCisJCSAgICAgICBfX2Z1bmNfXywgc2xhdmVfdHlwZSwgbW9k dWxlKTsNCit9DQorDQorc3RhdGljIHZvaWQgbWFza19tb2R1bGVfaXJxKHN0cnVjdCBtdGtfZGV2 YXBjX2NvbnRleHQgKmRldmFwY19jdHgsDQorCQkJICAgIGludCBzbGF2ZV90eXBlLCB1MzIgbW9k dWxlLCBib29sIG1hc2spDQorew0KKwl1MzIgcmVnX2luZGV4LCByZWdfb2Zmc2V0Ow0KKwl2b2lk IF9faW9tZW0gKnJlZzsNCisJdTMyIHZhbHVlOw0KKw0KKwlWSU9fTUFTS19TVEFfUkVHX0dFVCht b2R1bGUpOw0KKw0KKwlyZWcgPSBtdGtfZGV2YXBjX3BkX2dldChkZXZhcGNfY3R4LCBzbGF2ZV90 eXBlLCBWSU9fTUFTSywgcmVnX2luZGV4KTsNCisNCisJdmFsdWUgPSByZWFkbChyZWcpOw0KKwlp ZiAobWFzaykNCisJCXZhbHVlIHw9ICgweDEgPDwgcmVnX29mZnNldCk7DQorCWVsc2UNCisJCXZh bHVlICY9IH4oMHgxIDw8IHJlZ19vZmZzZXQpOw0KKw0KKwl3cml0ZWwodmFsdWUsIHJlZyk7DQor fQ0KKw0KKyNkZWZpbmUgVElNRU9VVF9NUwkJMTAwMDANCisNCitzdGF0aWMgaW50IHJlYWRfcG9s bF90aW1lb3V0KHZvaWQgX19pb21lbSAqYWRkciwgdTMyIG1hc2spDQorew0KKwl1bnNpZ25lZCBs b25nIHRpbWVvdXQgPSBqaWZmaWVzICsgbXNlY3NfdG9famlmZmllcyhUSU1FT1VUX01TKTsNCisN CisJZG8gew0KKwkJaWYgKHJlYWRsX3JlbGF4ZWQoYWRkcikgJiBtYXNrKQ0KKwkJCXJldHVybiAw Ow0KKw0KKwl9IHdoaWxlICghdGltZV9hZnRlcihqaWZmaWVzLCB0aW1lb3V0KSk7DQorDQorCXJl dHVybiAocmVhZGxfcmVsYXhlZChhZGRyKSAmIG1hc2spID8gMCA6IC1FVElNRURPVVQ7DQorfQ0K Kw0KKy8qDQorICogc3luY192aW9fZGJnIC0gc3RhcnQgdG8gZ2V0IHZpb2xhdGlvbiBpbmZvcm1h dGlvbiBieSBzZWxlY3RpbmcgdmlvbGF0aW9uDQorICoJCSAgZ3JvdXAgYW5kIGVuYWJsZSB2aW9s YXRpb24gc2hpZnQuDQorICoNCisgKiBSZXR1cm5zIHN5bmMgZG9uZSBvciBub3QNCisgKi8NCitz dGF0aWMgdTMyIHN5bmNfdmlvX2RiZyhzdHJ1Y3QgbXRrX2RldmFwY19jb250ZXh0ICpkZXZhcGNf Y3R4LCBpbnQgc2xhdmVfdHlwZSwNCisJCQl1MzIgc2hpZnRfYml0KQ0KK3sNCisJdm9pZCBfX2lv bWVtICpwZF92aW9fc2hpZnRfc3RhX3JlZzsNCisJdm9pZCBfX2lvbWVtICpwZF92aW9fc2hpZnRf c2VsX3JlZzsNCisJdm9pZCBfX2lvbWVtICpwZF92aW9fc2hpZnRfY29uX3JlZzsNCisJdTMyIHN5 bmNfZG9uZSA9IDA7DQorDQorCXBkX3Zpb19zaGlmdF9zdGFfcmVnID0gbXRrX2RldmFwY19wZF9n ZXQoZGV2YXBjX2N0eCwgc2xhdmVfdHlwZSwNCisJCQkJCQkgVklPX1NISUZUX1NUQSwgMCk7DQor CXBkX3Zpb19zaGlmdF9zZWxfcmVnID0gbXRrX2RldmFwY19wZF9nZXQoZGV2YXBjX2N0eCwgc2xh dmVfdHlwZSwNCisJCQkJCQkgVklPX1NISUZUX1NFTCwgMCk7DQorCXBkX3Zpb19zaGlmdF9jb25f cmVnID0gbXRrX2RldmFwY19wZF9nZXQoZGV2YXBjX2N0eCwgc2xhdmVfdHlwZSwNCisJCQkJCQkg VklPX1NISUZUX0NPTiwgMCk7DQorDQorCXdyaXRlbCgweDEgPDwgc2hpZnRfYml0LCBwZF92aW9f c2hpZnRfc2VsX3JlZyk7DQorCXdyaXRlbCgweDEsIHBkX3Zpb19zaGlmdF9jb25fcmVnKTsNCisN CisJaWYgKCFyZWFkX3BvbGxfdGltZW91dChwZF92aW9fc2hpZnRfY29uX3JlZywgMHgyKSkNCisJ CXN5bmNfZG9uZSA9IDE7DQorCWVsc2UNCisJCXByX2VycihQRlggIiVzOiBTaGlmdCB2aW9sYXRp b24gaW5mbyBmYWlsZWRcbiIsIF9fZnVuY19fKTsNCisNCisJLyogRGlzYWJsZSBzaGlmdCBtZWNo YW5pc20gKi8NCisJd3JpdGVsKDB4MCwgcGRfdmlvX3NoaWZ0X2Nvbl9yZWcpOw0KKwl3cml0ZWwo MHgwLCBwZF92aW9fc2hpZnRfc2VsX3JlZyk7DQorCXdyaXRlbCgweDEgPDwgc2hpZnRfYml0LCBw ZF92aW9fc2hpZnRfc3RhX3JlZyk7DQorDQorCXJldHVybiBzeW5jX2RvbmU7DQorfQ0KKw0KK3N0 YXRpYyB2b2lkIGRldmFwY192aW9faW5mb19wcmludChzdHJ1Y3QgbXRrX2RldmFwY19jb250ZXh0 ICpkZXZhcGNfY3R4KQ0KK3sNCisJc3RydWN0IG10a19kZXZhcGNfdmlvX2luZm8gKnZpb19pbmZv ID0gZGV2YXBjX2N0eC0+dmlvX2luZm87DQorDQorCS8qIFByaW50IHZpb2xhdGlvbiBpbmZvcm1h dGlvbiAqLw0KKwlpZiAodmlvX2luZm8tPndyaXRlKQ0KKwkJcHJfaW5mbyhQRlggIldyaXRlIFZp b2xhdGlvblxuIik7DQorCWVsc2UgaWYgKHZpb19pbmZvLT5yZWFkKQ0KKwkJcHJfaW5mbyhQRlgg IlJlYWQgVmlvbGF0aW9uXG4iKTsNCisNCisJcHJfaW5mbyhQRlggIiVzJXgsICVzJXgsICVzJXgs ICVzJXhcbiIsDQorCQkiVmlvIEFkZHI6MHgiLCB2aW9faW5mby0+dmlvX2FkZHIsDQorCQkiSGln aDoweCIsIHZpb19pbmZvLT52aW9fYWRkcl9oaWdoLA0KKwkJIkJ1cyBJRDoweCIsIHZpb19pbmZv LT5tYXN0ZXJfaWQsDQorCQkiRG9tIElEOjB4IiwgdmlvX2luZm8tPmRvbWFpbl9pZCk7DQorfQ0K Kw0KK3N0YXRpYyB2b2lkIGRldmFwY19leHRyYWN0X3Zpb19kYmcoc3RydWN0IG10a19kZXZhcGNf Y29udGV4dCAqZGV2YXBjX2N0eCwNCisJCQkJICAgaW50IHNsYXZlX3R5cGUpDQorew0KKwl2b2lk IF9faW9tZW0gKnZpb19kYmcwX3JlZywgKnZpb19kYmcxX3JlZzsNCisJc3RydWN0IG10a19kZXZh cGNfdmlvX2RiZ3NfZGVzYyAqdmlvX2RiZ3M7DQorCXN0cnVjdCBtdGtfZGV2YXBjX3Zpb19pbmZv ICp2aW9faW5mbzsNCisJdTMyIGRiZzA7DQorDQorCXZpb19kYmcwX3JlZyA9IG10a19kZXZhcGNf cGRfZ2V0KGRldmFwY19jdHgsIHNsYXZlX3R5cGUsIFZJT19EQkcwLCAwKTsNCisJdmlvX2RiZzFf cmVnID0gbXRrX2RldmFwY19wZF9nZXQoZGV2YXBjX2N0eCwgc2xhdmVfdHlwZSwgVklPX0RCRzEs IDApOw0KKw0KKwl2aW9fZGJncyA9IGRldmFwY19jdHgtPnZpb19kYmdzX2Rlc2M7DQorCXZpb19p bmZvID0gZGV2YXBjX2N0eC0+dmlvX2luZm87DQorDQorCS8qIEV4dHJhY3QgdmlvbGF0aW9uIGlu Zm9ybWF0aW9uICovDQorCWRiZzAgPSByZWFkbCh2aW9fZGJnMF9yZWcpOw0KKwl2aW9faW5mby0+ dmlvX2FkZHIgPSByZWFkbCh2aW9fZGJnMV9yZWcpOw0KKw0KKwl2aW9faW5mby0+bWFzdGVyX2lk ID0gKGRiZzAgJiB2aW9fZGJnc1tNU1RJRF0ubWFzaykgPj4NCisJCQkgICAgICB2aW9fZGJnc1tN U1RJRF0uc3RhcnRfYml0Ow0KKwl2aW9faW5mby0+ZG9tYWluX2lkID0gKGRiZzAgJiB2aW9fZGJn c1tETU5JRF0ubWFzaykgPj4NCisJCQkgICAgICB2aW9fZGJnc1tETU5JRF0uc3RhcnRfYml0Ow0K Kwl2aW9faW5mby0+d3JpdGUgPSAoKGRiZzAgJiB2aW9fZGJnc1tWSU9fV10ubWFzaykgPj4NCisJ CQkgICB2aW9fZGJnc1tWSU9fV10uc3RhcnRfYml0KSA9PSAxOw0KKwl2aW9faW5mby0+cmVhZCA9 ICgoZGJnMCAmIHZpb19kYmdzW1ZJT19SXS5tYXNrKSA+Pg0KKwkJCSAgdmlvX2RiZ3NbVklPX1Jd LnN0YXJ0X2JpdCkgPT0gMTsNCisJdmlvX2luZm8tPnZpb19hZGRyX2hpZ2ggPSAoZGJnMCAmIHZp b19kYmdzW0FERFJfSF0ubWFzaykgPj4NCisJCQkJICB2aW9fZGJnc1tBRERSX0hdLnN0YXJ0X2Jp dDsNCisNCisJZGV2YXBjX3Zpb19pbmZvX3ByaW50KGRldmFwY19jdHgpOw0KK30NCisNCisvKg0K KyAqIG10a19kZXZhcGNfZHVtcF92aW9fZGJnIC0gc2hpZnQgJiBkdW1wIHRoZSB2aW9sYXRpb24g ZGVidWcgaW5mb3JtYXRpb24uDQorICovDQorc3RhdGljIGJvb2wgbXRrX2RldmFwY19kdW1wX3Zp b19kYmcoc3RydWN0IG10a19kZXZhcGNfY29udGV4dCAqZGV2YXBjX2N0eCwNCisJCQkJICAgIGlu dCBzbGF2ZV90eXBlLCBpbnQgKnZpb19pZHgpDQorew0KKwljb25zdCBzdHJ1Y3QgbXRrX2Rldmlj ZV9pbmZvICoqZGV2aWNlX2luZm87DQorCXUzMiBzaGlmdF9iaXQ7DQorCWludCBpOw0KKw0KKwlk ZXZpY2VfaW5mbyA9IGRldmFwY19jdHgtPmRldmljZV9pbmZvOw0KKw0KKwlmb3IgKGkgPSAwOyBp IDwgZ2V0X3Zpb19zbGF2ZV9udW0oc2xhdmVfdHlwZSk7IGkrKykgew0KKwkJKnZpb19pZHggPSBk ZXZpY2VfaW5mb1tzbGF2ZV90eXBlXVtpXS52aW9faW5kZXg7DQorDQorCQlpZiAoY2hlY2tfdmlv X21hc2soZGV2YXBjX2N0eCwgc2xhdmVfdHlwZSwgKnZpb19pZHgpKQ0KKwkJCWNvbnRpbnVlOw0K Kw0KKwkJaWYgKCFjaGVja192aW9fc3RhdHVzKGRldmFwY19jdHgsIHNsYXZlX3R5cGUsICp2aW9f aWR4KSkNCisJCQljb250aW51ZTsNCisNCisJCXNoaWZ0X2JpdCA9IGdldF9zaGlmdF9ncm91cChk ZXZhcGNfY3R4LCBzbGF2ZV90eXBlLCAqdmlvX2lkeCk7DQorDQorCQlpZiAoIXN5bmNfdmlvX2Ri ZyhkZXZhcGNfY3R4LCBzbGF2ZV90eXBlLCBzaGlmdF9iaXQpKQ0KKwkJCWNvbnRpbnVlOw0KKw0K KwkJZGV2YXBjX2V4dHJhY3RfdmlvX2RiZyhkZXZhcGNfY3R4LCBzbGF2ZV90eXBlKTsNCisNCisJ CXJldHVybiB0cnVlOw0KKwl9DQorDQorCXJldHVybiBmYWxzZTsNCit9DQorDQorLyoNCisgKiBk ZXZhcGNfdmlvbGF0aW9uX2lycSAtIHRoZSBkZXZhcGMgSW50ZXJydXB0IFNlcnZpY2UgUm91dGlu ZSAoSVNSKSB3aWxsIGR1bXANCisgKgkJCSAgdmlvbGF0aW9uIGluZm9ybWF0aW9uIGluY2x1ZGlu ZyB3aGljaCBtYXN0ZXIgdmlvbGF0ZXMNCisgKgkJCSAgYWNjZXNzIHNsYXZlLg0KKyAqLw0KK3N0 YXRpYyBpcnFyZXR1cm5fdCBkZXZhcGNfdmlvbGF0aW9uX2lycShpbnQgaXJxX251bWJlciwNCisJ CQkJCXN0cnVjdCBtdGtfZGV2YXBjX2NvbnRleHQgKmRldmFwY19jdHgpDQorew0KKwljb25zdCBz dHJ1Y3QgbXRrX2RldmljZV9pbmZvICoqZGV2aWNlX2luZm87DQorCWludCBzbGF2ZV90eXBlX251 bTsNCisJaW50IHZpb19pZHggPSAtMTsNCisJaW50IHNsYXZlX3R5cGU7DQorDQorCXNsYXZlX3R5 cGVfbnVtID0gZGV2YXBjX2N0eC0+c2xhdmVfdHlwZV9udW07DQorCWRldmljZV9pbmZvID0gZGV2 YXBjX2N0eC0+ZGV2aWNlX2luZm87DQorDQorCWZvciAoc2xhdmVfdHlwZSA9IDA7IHNsYXZlX3R5 cGUgPCBzbGF2ZV90eXBlX251bTsgc2xhdmVfdHlwZSsrKSB7DQorCQlpZiAoIW10a19kZXZhcGNf ZHVtcF92aW9fZGJnKGRldmFwY19jdHgsIHNsYXZlX3R5cGUsICZ2aW9faWR4KSkNCisJCQljb250 aW51ZTsNCisNCisJCS8qIEVuc3VyZSB0aGF0IHZpb2xhdGlvbiBpbmZvIGFyZSB3cml0dGVuIGJl Zm9yZQ0KKwkJICogZnVydGhlciBvcGVyYXRpb25zDQorCQkgKi8NCisJCXNtcF9tYigpOw0KKw0K KwkJbWFza19tb2R1bGVfaXJxKGRldmFwY19jdHgsIHNsYXZlX3R5cGUsIHZpb19pZHgsIHRydWUp Ow0KKw0KKwkJY2xlYXJfdmlvX3N0YXR1cyhkZXZhcGNfY3R4LCBzbGF2ZV90eXBlLCB2aW9faWR4 KTsNCisNCisJCW1hc2tfbW9kdWxlX2lycShkZXZhcGNfY3R4LCBzbGF2ZV90eXBlLCB2aW9faWR4 LCBmYWxzZSk7DQorCX0NCisNCisJcmV0dXJuIElSUV9IQU5ETEVEOw0KK30NCisNCisvKg0KKyAq IHN0YXJ0X2RldmFwYyAtIGluaXRpYWxpemUgZGV2YXBjIHN0YXR1cyBhbmQgc3RhcnQgcmVjZWl2 aW5nIGludGVycnVwdA0KKyAqCQkgIHdoaWxlIGRldmFwYyB2aW9sYXRpb24gaXMgdHJpZ2dlcmVk Lg0KKyAqLw0KK3N0YXRpYyB2b2lkIHN0YXJ0X2RldmFwYyhzdHJ1Y3QgbXRrX2RldmFwY19jb250 ZXh0ICpkZXZhcGNfY3R4KQ0KK3sNCisJY29uc3Qgc3RydWN0IG10a19kZXZpY2VfaW5mbyAqKmRl dmljZV9pbmZvOw0KKwl2b2lkIF9faW9tZW0gKnBkX3Zpb19zaGlmdF9zdGFfcmVnOw0KKwl2b2lk IF9faW9tZW0gKnBkX2FwY19jb25fcmVnOw0KKwl1MzIgdmlvX3NoaWZ0X3N0YTsNCisJaW50IHNs YXZlX3R5cGUsIHNsYXZlX3R5cGVfbnVtOw0KKwlpbnQgaSwgdmlvX2lkeDsNCisNCisJZGV2aWNl X2luZm8gPSBkZXZhcGNfY3R4LT5kZXZpY2VfaW5mbzsNCisJc2xhdmVfdHlwZV9udW0gPSBkZXZh cGNfY3R4LT5zbGF2ZV90eXBlX251bTsNCisNCisJZm9yIChzbGF2ZV90eXBlID0gMDsgc2xhdmVf dHlwZSA8IHNsYXZlX3R5cGVfbnVtOyBzbGF2ZV90eXBlKyspIHsNCisJCXBkX2FwY19jb25fcmVn ID0gbXRrX2RldmFwY19wZF9nZXQoZGV2YXBjX2N0eCwgc2xhdmVfdHlwZSwNCisJCQkJCQkgICBB UENfQ09OLCAwKTsNCisJCXBkX3Zpb19zaGlmdF9zdGFfcmVnID0gbXRrX2RldmFwY19wZF9nZXQo ZGV2YXBjX2N0eCwgc2xhdmVfdHlwZSwNCisJCQkJCQkJIFZJT19TSElGVF9TVEEsIDApOw0KKwkJ aWYgKCFwZF9hcGNfY29uX3JlZyB8fCAhcGRfdmlvX3NoaWZ0X3N0YV9yZWcpDQorCQkJcmV0dXJu Ow0KKw0KKwkJLyogQ2xlYXIgZGV2YXBjIHZpb2xhdGlvbiBzdGF0dXMgKi8NCisJCXdyaXRlbChC SVQoMzEpLCBwZF9hcGNfY29uX3JlZyk7DQorDQorCQkvKiBDbGVhciB2aW9sYXRpb24gc2hpZnQg c3RhdHVzICovDQorCQl2aW9fc2hpZnRfc3RhID0gcmVhZGwocGRfdmlvX3NoaWZ0X3N0YV9yZWcp Ow0KKwkJaWYgKHZpb19zaGlmdF9zdGEpDQorCQkJd3JpdGVsKHZpb19zaGlmdF9zdGEsIHBkX3Zp b19zaGlmdF9zdGFfcmVnKTsNCisNCisJCS8qIENsZWFyIHNsYXZlIHZpb2xhdGlvbiBzdGF0dXMg Ki8NCisJCWZvciAoaSA9IDA7IGkgPCBnZXRfdmlvX3NsYXZlX251bShzbGF2ZV90eXBlKTsgaSsr KSB7DQorCQkJdmlvX2lkeCA9IGRldmljZV9pbmZvW3NsYXZlX3R5cGVdW2ldLnZpb19pbmRleDsN CisNCisJCQljbGVhcl92aW9fc3RhdHVzKGRldmFwY19jdHgsIHNsYXZlX3R5cGUsIHZpb19pZHgp Ow0KKw0KKwkJCW1hc2tfbW9kdWxlX2lycShkZXZhcGNfY3R4LCBzbGF2ZV90eXBlLCB2aW9faWR4 LCBmYWxzZSk7DQorCQl9DQorCX0NCit9DQorDQorc3RhdGljIGludCBtdGtfZGV2YXBjX3Byb2Jl KHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpDQorew0KKwlzdHJ1Y3QgZGV2aWNlX25vZGUg Km5vZGUgPSBwZGV2LT5kZXYub2Zfbm9kZTsNCisJc3RydWN0IG10a19kZXZhcGNfY29udGV4dCAq ZGV2YXBjX2N0eDsNCisJc3RydWN0IGNsayAqZGV2YXBjX2luZnJhX2NsazsNCisJdTMyIHZpb19k YmdzX251bSwgcGRzX251bTsNCisJdTggc2xhdmVfdHlwZV9udW07DQorCXUzMiBkZXZhcGNfaXJx Ow0KKwlzaXplX3Qgc2l6ZTsNCisJaW50IGksIHJldDsNCisNCisJaWYgKElTX0VSUihub2RlKSkN CisJCXJldHVybiAtRU5PREVWOw0KKw0KKwlkZXZhcGNfY3R4ID0gZGV2bV9remFsbG9jKCZwZGV2 LT5kZXYsIHNpemVvZihzdHJ1Y3QgbXRrX2RldmFwY19jb250ZXh0KSwNCisJCQkJICBHRlBfS0VS TkVMKTsNCisJaWYgKCFkZXZhcGNfY3R4KQ0KKwkJcmV0dXJuIC1FTk9NRU07DQorDQorCWlmIChv Zl9wcm9wZXJ0eV9yZWFkX3U4KG5vZGUsICJtZWRpYXRlay1zbHZfdHlwZV9udW0iLCAmc2xhdmVf dHlwZV9udW0pKQ0KKwkJcmV0dXJuIC1FTlhJTzsNCisNCisJZGV2YXBjX2N0eC0+c2xhdmVfdHlw ZV9udW0gPSBzbGF2ZV90eXBlX251bTsNCisNCisJc2l6ZSA9IHNsYXZlX3R5cGVfbnVtICogc2l6 ZW9mKHZvaWQgKik7DQorCWRldmFwY19jdHgtPmRldmFwY19wZF9iYXNlID0gZGV2bV9remFsbG9j KCZwZGV2LT5kZXYsIHNpemUsIEdGUF9LRVJORUwpOw0KKwlpZiAoIWRldmFwY19jdHgtPmRldmFw Y19wZF9iYXNlKQ0KKwkJcmV0dXJuIC1FTk9NRU07DQorDQorCXNpemUgPSBzbGF2ZV90eXBlX251 bSAqIHNpemVvZihzdHJ1Y3QgbXRrX2RldmljZV9pbmZvICopOw0KKwlkZXZhcGNfY3R4LT5kZXZp Y2VfaW5mbyA9IGRldm1fa3phbGxvYygmcGRldi0+ZGV2LCBzaXplLCBHRlBfS0VSTkVMKTsNCisJ aWYgKCFkZXZhcGNfY3R4LT5kZXZpY2VfaW5mbykNCisJCXJldHVybiAtRU5PTUVNOw0KKw0KKwlm b3IgKGkgPSAwOyBpIDwgc2xhdmVfdHlwZV9udW07IGkrKykgew0KKwkJZGV2YXBjX2N0eC0+ZGV2 YXBjX3BkX2Jhc2VbaV0gPSBvZl9pb21hcChub2RlLCBpKTsNCisJCWlmICghZGV2YXBjX2N0eC0+ ZGV2YXBjX3BkX2Jhc2VbaV0pDQorCQkJcmV0dXJuIC1FSU5WQUw7DQorDQorCQlpZiAoaSA9PSAw KQ0KKwkJCWRldmFwY19jdHgtPmRldmljZV9pbmZvW2ldID0gbXRrX2RldmljZXNfaW5mcmE7DQor CX0NCisNCisJc2l6ZSA9IHNpemVvZihzdHJ1Y3QgbXRrX2RldmFwY192aW9faW5mbyk7DQorCWRl dmFwY19jdHgtPnZpb19pbmZvID0gZGV2bV9remFsbG9jKCZwZGV2LT5kZXYsIHNpemUsIEdGUF9L RVJORUwpOw0KKwlpZiAoIWRldmFwY19jdHgtPnZpb19pbmZvKQ0KKwkJcmV0dXJuIC1FTk9NRU07 DQorDQorCXZpb19kYmdzX251bSA9IG9mX3Byb3BlcnR5X2NvdW50X3UzMl9lbGVtcyhub2RlLCAi bWVkaWF0ZWstdmlvX2RiZ3MiKTsNCisJaWYgKHZpb19kYmdzX251bSA8PSAwKQ0KKwkJcmV0dXJu IC1FTlhJTzsNCisNCisJc2l6ZSA9ICh2aW9fZGJnc19udW0gLyAyKSAqIHNpemVvZihzdHJ1Y3Qg bXRrX2RldmFwY192aW9fZGJnc19kZXNjKTsNCisJZGV2YXBjX2N0eC0+dmlvX2RiZ3NfZGVzYyA9 IGRldm1fa3phbGxvYygmcGRldi0+ZGV2LCBzaXplLCBHRlBfS0VSTkVMKTsNCisJaWYgKCFkZXZh cGNfY3R4LT52aW9fZGJnc19kZXNjKQ0KKwkJcmV0dXJuIC1FTk9NRU07DQorDQorCWZvciAoaSA9 IDA7IGkgPCB2aW9fZGJnc19udW0gLyAyOyBpKyspIHsNCisJCWlmIChvZl9wcm9wZXJ0eV9yZWFk X3UzMl9pbmRleChub2RlLCAibWVkaWF0ZWstdmlvX2RiZ3MiLA0KKwkJCQkJICAgICAgIGkgKiAy LA0KKwkJCQkJICAgICAgICZkZXZhcGNfY3R4LT52aW9fZGJnc19kZXNjW2ldLm1hc2spKQ0KKwkJ CXJldHVybiAtRU5YSU87DQorDQorCQlpZiAob2ZfcHJvcGVydHlfcmVhZF91MzJfaW5kZXgobm9k ZSwgIm1lZGlhdGVrLXZpb19kYmdzIiwNCisJCQkJCSAgICAgICAoaSAqIDIpICsgMSwNCisJCQkJ CSAgICAgICAmZGV2YXBjX2N0eC0+dmlvX2RiZ3NfZGVzY1tpXS5zdGFydF9iaXQpKQ0KKwkJCXJl dHVybiAtRU5YSU87DQorCX0NCisNCisJcGRzX251bSA9IG9mX3Byb3BlcnR5X2NvdW50X3UzMl9l bGVtcyhub2RlLCAibWVkaWF0ZWstcGRzX29mZnNldCIpOw0KKwlpZiAocGRzX251bSA8PSAwKQ0K KwkJcmV0dXJuIC1FTlhJTzsNCisNCisJc2l6ZSA9IHBkc19udW0gKiBzaXplb2YodTMyKTsNCisJ ZGV2YXBjX2N0eC0+cGRzX29mZnNldCA9IGRldm1fa3phbGxvYygmcGRldi0+ZGV2LCBzaXplLCBH RlBfS0VSTkVMKTsNCisJaWYgKCFkZXZhcGNfY3R4LT5wZHNfb2Zmc2V0KQ0KKwkJcmV0dXJuIC1F Tk9NRU07DQorDQorCWZvciAoaSA9IDA7IGkgPCBwZHNfbnVtOyBpKyspIHsNCisJCWlmIChvZl9w cm9wZXJ0eV9yZWFkX3UzMl9pbmRleChub2RlLCAibWVkaWF0ZWstcGRzX29mZnNldCIsIGksDQor CQkJCQkgICAgICAgJmRldmFwY19jdHgtPnBkc19vZmZzZXRbaV0pKQ0KKwkJCXJldHVybiAtRU5Y SU87DQorCX0NCisNCisJZGV2YXBjX2lycSA9IGlycV9vZl9wYXJzZV9hbmRfbWFwKG5vZGUsIDAp Ow0KKwlpZiAoIWRldmFwY19pcnEpDQorCQlyZXR1cm4gLUVJTlZBTDsNCisNCisJZGV2YXBjX2lu ZnJhX2NsayA9IGRldm1fY2xrX2dldCgmcGRldi0+ZGV2LCAiZGV2YXBjLWluZnJhLWNsb2NrIik7 DQorCWlmIChJU19FUlIoZGV2YXBjX2luZnJhX2NsaykpDQorCQlyZXR1cm4gLUVJTlZBTDsNCisN CisJaWYgKGNsa19wcmVwYXJlX2VuYWJsZShkZXZhcGNfaW5mcmFfY2xrKSkNCisJCXJldHVybiAt RUlOVkFMOw0KKw0KKwlzdGFydF9kZXZhcGMoZGV2YXBjX2N0eCk7DQorDQorCXJldCA9IGRldm1f cmVxdWVzdF9pcnEoJnBkZXYtPmRldiwgZGV2YXBjX2lycSwNCisJCQkgICAgICAgKGlycV9oYW5k bGVyX3QpZGV2YXBjX3Zpb2xhdGlvbl9pcnEsDQorCQkJICAgICAgIElSUUZfVFJJR0dFUl9OT05F LCAiZGV2YXBjIiwgZGV2YXBjX2N0eCk7DQorCWlmIChyZXQpDQorCQlyZXR1cm4gcmV0Ow0KKw0K KwlyZXR1cm4gMDsNCit9DQorDQorc3RhdGljIGludCBtdGtfZGV2YXBjX3JlbW92ZShzdHJ1Y3Qg cGxhdGZvcm1fZGV2aWNlICpkZXYpDQorew0KKwlyZXR1cm4gMDsNCit9DQorDQorc3RhdGljIGNv bnN0IHN0cnVjdCBvZl9kZXZpY2VfaWQgbXRrX2RldmFwY19kdF9tYXRjaFtdID0gew0KKwl7IC5j b21wYXRpYmxlID0gIm1lZGlhdGVrLG10Njc3OS1kZXZhcGMiIH0sDQorCXt9LA0KK307DQorDQor c3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgbXRrX2RldmFwY19kcml2ZXIgPSB7DQorCS5w cm9iZSA9IG10a19kZXZhcGNfcHJvYmUsDQorCS5yZW1vdmUgPSBtdGtfZGV2YXBjX3JlbW92ZSwN CisJLmRyaXZlciA9IHsNCisJCS5uYW1lID0gS0JVSUxEX01PRE5BTUUsDQorCQkub2ZfbWF0Y2hf dGFibGUgPSBtdGtfZGV2YXBjX2R0X21hdGNoLA0KKwl9LA0KK307DQorDQorbW9kdWxlX3BsYXRm b3JtX2RyaXZlcihtdGtfZGV2YXBjX2RyaXZlcik7DQorDQorTU9EVUxFX0RFU0NSSVBUSU9OKCJN ZWRpYXRlayBEZXZpY2UgQVBDIERyaXZlciIpOw0KK01PRFVMRV9BVVRIT1IoIk5lYWwgTGl1IDxu ZWFsLmxpdUBtZWRpYXRlay5jb20+Iik7DQorTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOw0KZGlmZiAt LWdpdCBhL2RyaXZlcnMvc29jL21lZGlhdGVrL210ay1kZXZhcGMuaCBiL2RyaXZlcnMvc29jL21l ZGlhdGVrL210ay1kZXZhcGMuaA0KbmV3IGZpbGUgbW9kZSAxMDA2NDQNCmluZGV4IDAwMDAwMDAu LmFiMmNiMTQNCi0tLSAvZGV2L251bGwNCisrKyBiL2RyaXZlcnMvc29jL21lZGlhdGVrL210ay1k ZXZhcGMuaA0KQEAgLTAsMCArMSw2NzAgQEANCisvKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjog R1BMLTIuMCAqLw0KKy8qDQorICogQ29weXJpZ2h0IChDKSAyMDIwIE1lZGlhVGVrIEluYy4NCisg Ki8NCisNCisjaWZuZGVmIF9fTVRLX0RFVkFQQ19IX18NCisjZGVmaW5lIF9fTVRLX0RFVkFQQ19I X18NCisNCisjZGVmaW5lIFBGWAkJCSJbREVWQVBDXTogIg0KKw0KKyNkZWZpbmUgVklPX01BU0tf U1RBX1JFR19HRVQobSkgXA0KKyh7IFwNCisJdHlwZW9mKG0pIChfbSkgPSAobSk7IFwNCisJcmVn X2luZGV4ID0gX20gLyAzMjsgXA0KKwlyZWdfb2Zmc2V0ID0gX20gJSAzMjsgXA0KK30pDQorDQor ZW51bSBERVZBUENfUERfUkVHX1RZUEUgew0KKwlWSU9fTUFTSyA9IDAsDQorCVZJT19TVEEsDQor CVZJT19EQkcwLA0KKwlWSU9fREJHMSwNCisJQVBDX0NPTiwNCisJVklPX1NISUZUX1NUQSwNCisJ VklPX1NISUZUX1NFTCwNCisJVklPX1NISUZUX0NPTiwNCisJUERfUkVHX1RZUEVfTlVNLA0KK307 DQorDQorZW51bSBERVZBUENfVklPX0RCR1NfVFlQRSB7DQorCU1TVElEID0gMCwNCisJRE1OSUQs DQorCVZJT19XLA0KKwlWSU9fUiwNCisJQUREUl9ILA0KK307DQorDQorc3RydWN0IG10a19kZXZp Y2VfaW5mbyB7DQorCWludCBzeXNfaW5kZXg7DQorCWludCBjdHJsX2luZGV4Ow0KKwlpbnQgdmlv X2luZGV4Ow0KK307DQorDQorc3RhdGljIHN0cnVjdCBtdGtfZGV2aWNlX2luZm8gbXRrX2Rldmlj ZXNfaW5mcmFbXSA9IHsNCisJLyogc3lzX2lkeCwgY3RybF9pZHgsIHZpb19pZHggKi8NCisJLyog MCAqLw0KKwl7MCwgMCwgMH0sDQorCXswLCAxLCAxfSwNCisJezAsIDIsIDJ9LA0KKwl7MCwgMywg M30sDQorCXswLCA0LCA0fSwNCisJezAsIDUsIDV9LA0KKwl7MCwgNiwgNn0sDQorCXswLCA3LCA3 fSwNCisJezAsIDgsIDh9LA0KKwl7MCwgOSwgOX0sDQorDQorCS8qIDEwICovDQorCXswLCAxMCwg MTB9LA0KKwl7MCwgMTEsIDExfSwNCisJezAsIDEyLCAxMn0sDQorCXswLCAxMywgMTN9LA0KKwl7 MCwgMTQsIDE0fSwNCisJezAsIDE1LCAxNX0sDQorCXswLCAxNiwgMTZ9LA0KKwl7MCwgMTcsIDE3 fSwNCisJezAsIDE4LCAxOH0sDQorCXswLCAxOSwgMTl9LA0KKw0KKwkvKiAyMCAqLw0KKwl7MCwg MjAsIDIwfSwNCisJezAsIDIxLCAyMX0sDQorCXswLCAyMiwgMjJ9LA0KKwl7MCwgMjMsIDIzfSwN CisJezAsIDI0LCAyNH0sDQorCXswLCAyNSwgMjV9LA0KKwl7MCwgMjYsIDI2fSwNCisJezAsIDI3 LCAyN30sDQorCXswLCAyOCwgMjh9LA0KKwl7MCwgMjksIDI5fSwNCisNCisJLyogMzAgKi8NCisJ ezAsIDMwLCAzMH0sDQorCXswLCAzMSwgMzF9LA0KKwl7MCwgMzIsIDMyfSwNCisJezAsIDMzLCA3 N30sDQorCXswLCAzNCwgNzh9LA0KKwl7MCwgMzUsIDc5fSwNCisJezAsIDM1LCA4MH0sDQorCXsw LCAzNywgMzd9LA0KKwl7MCwgMzgsIDM4fSwNCisJezAsIDM5LCAzOX0sDQorDQorCS8qIDQwICov DQorCXswLCA0MCwgNDB9LA0KKwl7MCwgNDEsIDQxfSwNCisJezAsIDQyLCA0Mn0sDQorCXswLCA0 MywgNDN9LA0KKwl7MCwgNDQsIDQ0fSwNCisJezAsIDQ1LCA0NX0sDQorCXswLCA0NiwgNDZ9LA0K Kwl7MCwgNDcsIDQ3fSwNCisJezAsIDQ4LCA0OH0sDQorCXswLCA0OSwgNDl9LA0KKw0KKwkvKiA1 MCAqLw0KKwl7MCwgNTAsIDUwfSwNCisJezAsIDUxLCA1MX0sDQorCXswLCA1MiwgNTJ9LA0KKwl7 MCwgNTMsIDUzfSwNCisJezAsIDU0LCA1NH0sDQorCXswLCA1NSwgNTV9LA0KKwl7MCwgNTYsIDU2 fSwNCisJezAsIDU3LCA1N30sDQorCXswLCA1OCwgNTh9LA0KKwl7MCwgNTksIDU5fSwNCisNCisJ LyogNjAgKi8NCisJezAsIDYwLCA2MH0sDQorCXswLCA2MSwgNjF9LA0KKwl7MCwgNjIsIDYyfSwN CisJezAsIDYzLCA2M30sDQorCXswLCA2NCwgNjR9LA0KKwl7MCwgNjUsIDcwfSwNCisJezAsIDY2 LCA3MX0sDQorCXswLCA2NywgNzJ9LA0KKwl7MCwgNjgsIDczfSwNCisJezAsIDcwLCA4MX0sDQor DQorCS8qIDcwICovDQorCXswLCA3MSwgODJ9LA0KKwl7MCwgNzIsIDgzfSwNCisJezAsIDczLCA4 NH0sDQorCXswLCA3NCwgODV9LA0KKwl7MCwgNzUsIDg2fSwNCisJezAsIDc2LCA4N30sDQorCXsw LCA3NywgODh9LA0KKwl7MCwgNzgsIDg5fSwNCisJezAsIDc5LCA5MH0sDQorCXswLCA4MCwgOTF9 LA0KKw0KKwkvKiA4MCAqLw0KKwl7MCwgODEsIDkyfSwNCisJezAsIDgyLCA5M30sDQorCXswLCA4 MywgOTR9LA0KKwl7MCwgODQsIDk1fSwNCisJezAsIDg1LCA5Nn0sDQorCXswLCA4NiwgOTd9LA0K Kwl7MCwgODcsIDk4fSwNCisJezAsIDg4LCA5OX0sDQorCXswLCA4OSwgMTAwfSwNCisJezAsIDkw LCAxMDF9LA0KKw0KKwkvKiA5MCAqLw0KKwl7MCwgOTEsIDEwMn0sDQorCXswLCA5MiwgMTAzfSwN CisJezAsIDkzLCAxMDR9LA0KKwl7MCwgOTQsIDEwNX0sDQorCXswLCA5NSwgMTA2fSwNCisJezAs IDk2LCAxMDd9LA0KKwl7MCwgOTcsIDEwOH0sDQorCXswLCA5OCwgMTA5fSwNCisJezAsIDExMCwg MTEwfSwNCisJezAsIDExMSwgMTExfSwNCisNCisJLyogMTAwICovDQorCXswLCAxMTIsIDExMn0s DQorCXswLCAxMTMsIDExM30sDQorCXswLCAxMTQsIDExNH0sDQorCXswLCAxMTUsIDExNX0sDQor CXswLCAxMTYsIDExNn0sDQorCXswLCAxMTcsIDExN30sDQorCXswLCAxMTgsIDExOH0sDQorCXsw LCAxMTksIDExOX0sDQorCXswLCAxMjAsIDEyMH0sDQorCXswLCAxMjEsIDEyMX0sDQorDQorCS8q IDExMCAqLw0KKwl7MCwgMTIyLCAxMjJ9LA0KKwl7MCwgMTIzLCAxMjN9LA0KKwl7MCwgMTI0LCAx MjR9LA0KKwl7MCwgMTI1LCAxMjV9LA0KKwl7MCwgMTI2LCAxMjZ9LA0KKwl7MCwgMTI3LCAxMjd9 LA0KKwl7MCwgMTI4LCAxMjh9LA0KKwl7MCwgMTI5LCAxMjl9LA0KKwl7MCwgMTMwLCAxMzB9LA0K Kwl7MCwgMTMxLCAxMzF9LA0KKw0KKwkvKiAxMjAgKi8NCisJezAsIDEzMiwgMTMyfSwNCisJezAs IDEzMywgMTMzfSwNCisJezAsIDEzNCwgMTM0fSwNCisJezAsIDEzNSwgMTM1fSwNCisJezAsIDEz NiwgMTM2fSwNCisJezAsIDEzNywgMTM3fSwNCisJezAsIDEzOCwgMTM4fSwNCisJezAsIDEzOSwg MTM5fSwNCisJezAsIDE0MCwgMTQwfSwNCisJezAsIDE0MSwgMTQxfSwNCisNCisJLyogMTMwICov DQorCXswLCAxNDIsIDE0Mn0sDQorCXswLCAxNDMsIDE0M30sDQorCXswLCAxNDQsIDE0NH0sDQor CXswLCAxNDUsIDE0NX0sDQorCXswLCAxNDYsIDE0Nn0sDQorCXswLCAxNDcsIDE0N30sDQorCXsw LCAxNDgsIDE0OH0sDQorCXswLCAxNDksIDE0OX0sDQorCXswLCAxNTAsIDE1MH0sDQorCXswLCAx NTEsIDE1MX0sDQorDQorCS8qIDE0MCAqLw0KKwl7MCwgMTUyLCAxNTJ9LA0KKwl7MCwgMTUzLCAx NTN9LA0KKwl7MCwgMTU0LCAxNTR9LA0KKwl7MCwgMTU1LCAxNTV9LA0KKwl7MCwgMTU2LCAxNTZ9 LA0KKwl7MCwgMTU3LCAxNTd9LA0KKwl7MCwgMTU4LCAxNTh9LA0KKwl7MCwgMTU5LCAxNTl9LA0K Kwl7MCwgMTYwLCAxNjB9LA0KKwl7MCwgMTYxLCAxNjF9LA0KKw0KKwkvKiAxNTAgKi8NCisJezAs IDE2MiwgMTYyfSwNCisJezAsIDE2MywgMTYzfSwNCisJezAsIDE2NCwgMTY0fSwNCisJezAsIDE2 NSwgMTY1fSwNCisJezAsIDE2NiwgMTY2fSwNCisJezAsIDE2NywgMTY3fSwNCisJezAsIDE2OCwg MTY4fSwNCisJezAsIDE2OSwgMTY5fSwNCisJezAsIDE3MCwgMTcwfSwNCisJezAsIDE3MSwgMTcx fSwNCisNCisJLyogMTYwICovDQorCXswLCAxNzIsIDE3Mn0sDQorCXswLCAxNzMsIDE3M30sDQor CXswLCAxNzQsIDE3NH0sDQorCXswLCAxNzUsIDE3NX0sDQorCXswLCAxNzYsIDE3Nn0sDQorCXsw LCAxNzcsIDE3N30sDQorCXswLCAxNzgsIDE3OH0sDQorCXswLCAxNzksIDE3OX0sDQorCXswLCAx ODAsIDE4MH0sDQorCXswLCAxODEsIDE4MX0sDQorDQorCS8qIDE3MCAqLw0KKwl7MCwgMTgyLCAx ODJ9LA0KKwl7MCwgMTgzLCAxODN9LA0KKwl7MCwgMTg0LCAxODR9LA0KKwl7MCwgMTg1LCAxODV9 LA0KKwl7MCwgMTg2LCAxODZ9LA0KKwl7MCwgMTg3LCAxODd9LA0KKwl7MCwgMTg4LCAxODh9LA0K Kwl7MCwgMTg5LCAxODl9LA0KKwl7MCwgMTkwLCAxOTB9LA0KKwl7MCwgMTkxLCAxOTF9LA0KKw0K KwkvKiAxODAgKi8NCisJezAsIDE5MiwgMTkyfSwNCisJezAsIDE5MywgMTkzfSwNCisJezAsIDE5 NCwgMTk0fSwNCisJezAsIDE5NSwgMTk1fSwNCisJezAsIDE5NiwgMTk2fSwNCisJezAsIDE5Nywg MTk3fSwNCisJezAsIDE5OCwgMTk4fSwNCisJezAsIDE5OSwgMTk5fSwNCisJezAsIDIwMCwgMjAw fSwNCisJezAsIDIwMSwgMjAxfSwNCisNCisJLyogMTkwICovDQorCXswLCAyMDIsIDIwMn0sDQor CXswLCAyMDMsIDIwM30sDQorCXswLCAyMDQsIDIwNH0sDQorCXswLCAyMDUsIDIwNX0sDQorCXsw LCAyMDYsIDIwNn0sDQorCXswLCAyMDcsIDIwN30sDQorCXswLCAyMDgsIDIwOH0sDQorCXswLCAy MDksIDIwOX0sDQorCXswLCAyMTAsIDIxMH0sDQorCXswLCAyMTEsIDIxMX0sDQorDQorCS8qIDIw MCAqLw0KKwl7MCwgMjEyLCAyMTJ9LA0KKwl7MCwgMjEzLCAyMTN9LA0KKwl7MCwgMjE0LCAyMTR9 LA0KKwl7MCwgMjE1LCAyMTV9LA0KKwl7MCwgMjE2LCAyMTZ9LA0KKwl7MCwgMjE3LCAyMTd9LA0K Kwl7MCwgMjE4LCAyMTh9LA0KKwl7MCwgMjE5LCAyMTl9LA0KKwl7MCwgMjIwLCAyMjB9LA0KKwl7 MCwgMjIxLCAyMjF9LA0KKw0KKwkvKiAyMTAgKi8NCisJezAsIDIyMiwgMjIyfSwNCisJezAsIDIy MywgMjIzfSwNCisJezAsIDIyNCwgMjI0fSwNCisJezAsIDIyNSwgMjI1fSwNCisJezAsIDIyNiwg MjI2fSwNCisJezAsIDIyNywgMjI3fSwNCisJezAsIDIyOCwgMjI4fSwNCisJezAsIDIyOSwgMjI5 fSwNCisJezAsIDIzMCwgMjMwfSwNCisJezAsIDIzMSwgMjMxfSwNCisNCisJLyogMjIwICovDQor CXsxLCAwLCAyMzJ9LA0KKwl7MSwgMSwgMjMzfSwNCisJezEsIDIsIDIzNH0sDQorCXsxLCAzLCAy MzV9LA0KKwl7MSwgNCwgMjM2fSwNCisJezEsIDUsIDIzN30sDQorCXsxLCA2LCAyMzh9LA0KKwl7 MSwgNywgMjM5fSwNCisJezEsIDgsIDI0MH0sDQorCXsxLCA5LCAyNDF9LA0KKw0KKwkvKiAyMzAg Ki8NCisJezEsIDEwLCAyNDJ9LA0KKwl7MSwgMTEsIDI0M30sDQorCXsxLCAxMiwgMjQ0fSwNCisJ ezEsIDEzLCAyNDV9LA0KKwl7MSwgMTQsIDI0Nn0sDQorCXsxLCAxNSwgMjQ3fSwNCisJezEsIDE2 LCAyNDh9LA0KKwl7MSwgMTcsIDI0OX0sDQorCXsxLCAxOCwgMjUwfSwNCisJezEsIDE5LCAyNTF9 LA0KKw0KKwkvKiAyNDAgKi8NCisJezEsIDIwLCAyNTJ9LA0KKwl7MSwgMjEsIDI1M30sDQorCXsx LCAyMiwgMjU0fSwNCisJezEsIDIzLCAyNTV9LA0KKwl7MSwgMjQsIDI1Nn0sDQorCXsxLCAyNSwg MjU3fSwNCisJezEsIDI2LCAyNTh9LA0KKwl7MSwgMjcsIDI1OX0sDQorCXsxLCAyOCwgMjYwfSwN CisJezEsIDI5LCAyNjF9LA0KKw0KKwkvKiAyNTAgKi8NCisJezEsIDMwLCAyNjJ9LA0KKwl7MSwg MzEsIDI2M30sDQorCXsxLCAzMiwgMjY0fSwNCisJezEsIDMzLCAyNjV9LA0KKwl7MSwgMzQsIDI2 Nn0sDQorCXsxLCAzNSwgMjY3fSwNCisJezEsIDM2LCAyNjh9LA0KKwl7MSwgMzcsIDI2OX0sDQor CXsxLCAzOCwgMjcwfSwNCisJezEsIDM5LCAyNzF9LA0KKw0KKwkvKiAyNjAgKi8NCisJezEsIDQw LCAyNzJ9LA0KKwl7MSwgNDEsIDI3M30sDQorCXsxLCA0MiwgMjc0fSwNCisJezEsIDQzLCAyNzV9 LA0KKwl7MSwgNDQsIDI3Nn0sDQorCXsxLCA0NSwgMjc3fSwNCisJezEsIDQ2LCAyNzh9LA0KKwl7 MSwgNDcsIDI3OX0sDQorCXsxLCA0OCwgMjgwfSwNCisJezEsIDQ5LCAyODF9LA0KKw0KKwkvKiAy NzAgKi8NCisJezEsIDUwLCAyODJ9LA0KKwl7MSwgNTEsIDI4M30sDQorCXsxLCA1MiwgMjg0fSwN CisJezEsIDUzLCAyODV9LA0KKwl7MSwgNTQsIDI4Nn0sDQorCXsxLCA1NSwgMjg3fSwNCisJezEs IDU2LCAyODh9LA0KKwl7MSwgNTcsIDI4OX0sDQorCXsxLCA1OCwgMjkwfSwNCisJezEsIDU5LCAy OTF9LA0KKw0KKwkvKiAyODAgKi8NCisJezEsIDYwLCAyOTJ9LA0KKwl7MSwgNjEsIDI5M30sDQor CXsxLCA2MiwgMjk0fSwNCisJezEsIDYzLCAyOTV9LA0KKwl7MSwgNjQsIDI5Nn0sDQorCXsxLCA2 NSwgMjk3fSwNCisJezEsIDY2LCAyOTh9LA0KKwl7MSwgNjcsIDI5OX0sDQorCXsxLCA2OCwgMzAw fSwNCisJezEsIDY5LCAzMDF9LA0KKw0KKwkvKiAyOTAgKi8NCisJezEsIDcwLCAzMDJ9LA0KKwl7 MSwgNzEsIDMwM30sDQorCXsxLCA3MiwgMzA0fSwNCisJezEsIDczLCAzMDV9LA0KKwl7MSwgNzQs IDMwNn0sDQorCXsxLCA3NSwgMzA3fSwNCisJezEsIDc2LCAzMDh9LA0KKwl7MSwgNzcsIDMwOX0s DQorCXsxLCA3OCwgMzEwfSwNCisJezEsIDc5LCAzMTF9LA0KKw0KKwkvKiAzMDAgKi8NCisJezEs IDgwLCAzMTJ9LA0KKwl7MSwgODEsIDMxM30sDQorCXsxLCA4MiwgMzE0fSwNCisJezEsIDgzLCAz MTV9LA0KKwl7MSwgODQsIDMxNn0sDQorCXsxLCA4NSwgMzE3fSwNCisJezEsIDg2LCAzMTh9LA0K Kwl7MSwgODcsIDMxOX0sDQorCXsxLCA4OCwgMzIwfSwNCisJezEsIDg5LCAzMjF9LA0KKw0KKwkv KiAzMTAgKi8NCisJezEsIDkwLCAzMjJ9LA0KKwl7MSwgOTEsIDMyM30sDQorCXsxLCA5MiwgMzI0 fSwNCisJezEsIDkzLCAzMjV9LA0KKwl7MSwgOTQsIDMyNn0sDQorCXsxLCA5NSwgMzI3fSwNCisJ ezEsIDk2LCAzMjh9LA0KKwl7MSwgOTcsIDMyOX0sDQorCXsxLCA5OCwgMzMwfSwNCisJezEsIDk5 LCAzMzF9LA0KKw0KKwkvKiAzMjAgKi8NCisJezEsIDEwMCwgMzMyfSwNCisJezEsIDEwMSwgMzMz fSwNCisJezEsIDEwMiwgMzM0fSwNCisJezEsIDEwMywgMzM1fSwNCisJezEsIDEwNCwgMzM2fSwN CisJezEsIDEwNSwgMzM3fSwNCisJezEsIDEwNiwgMzM4fSwNCisJezEsIDEwNywgMzM5fSwNCisJ ezEsIDEwOCwgMzQwfSwNCisJezEsIDEwOSwgMzQxfSwNCisNCisJLyogMzMwICovDQorCXsxLCAx MTAsIDM0Mn0sDQorCXsxLCAxMTEsIDM0M30sDQorCXsxLCAxMTIsIDM0NH0sDQorCXsxLCAxMTMs IDM0NX0sDQorCXsxLCAxMTQsIDM0Nn0sDQorCXsxLCAxMTUsIDM0N30sDQorCXsxLCAxMTYsIDM0 OH0sDQorCXsxLCAxMTcsIDM0OX0sDQorCXsxLCAxMTgsIDM1MH0sDQorCXsxLCAxMTksIDM1MX0s DQorDQorCS8qIDM0MCAqLw0KKwl7MSwgMTIwLCAzNTJ9LA0KKwl7MSwgMTIxLCAzNTN9LA0KKwl7 MSwgMTIyLCAzNTR9LA0KKwl7MSwgMTIzLCAzNTV9LA0KKwl7MSwgMTI0LCAzNTZ9LA0KKwl7MSwg MTI1LCAzNTd9LA0KKwl7MSwgMTI2LCAzNTh9LA0KKwl7MSwgMTI3LCAzNTl9LA0KKwl7MSwgMTI4 LCAzNjB9LA0KKwl7MSwgMTI5LCAzNjF9LA0KKw0KKwkvKiAzNTAgKi8NCisJezEsIDEzMCwgMzYy fSwNCisJezEsIDEzMSwgMzYzfSwNCisJezEsIDEzMiwgMzY0fSwNCisJezEsIDEzMywgMzY1fSwN CisJezEsIDEzNCwgMzY2fSwNCisJezEsIDEzNSwgMzY3fSwNCisJezEsIDEzNiwgMzY4fSwNCisJ ezEsIDEzNywgMzY5fSwNCisJezEsIDEzOCwgMzcwfSwNCisJezEsIDEzOSwgMzcxfSwNCisNCisJ LyogMzYwICovDQorCXsxLCAxNDAsIDM3Mn0sDQorCXsxLCAxNDEsIDM3M30sDQorCXsxLCAxNDIs IDM3NH0sDQorCXsxLCAxNDMsIDM3NX0sDQorCXsxLCAxNDQsIDM3Nn0sDQorCXsxLCAxNDUsIDM3 N30sDQorCXsxLCAxNDYsIDM3OH0sDQorCXsxLCAxNDcsIDM3OX0sDQorCXsxLCAxNDgsIDM4MH0s DQorCXsxLCAxNDksIDM4MX0sDQorDQorCS8qIDM3MCAqLw0KKwl7MSwgMTUwLCAzODJ9LA0KKwl7 MSwgMTUxLCAzODN9LA0KKwl7MSwgMTUyLCAzODR9LA0KKwl7MSwgMTUzLCAzODV9LA0KKwl7MSwg MTU0LCAzODZ9LA0KKwl7MSwgMTU1LCAzODd9LA0KKwl7MSwgMTU2LCAzODh9LA0KKwl7MSwgMTU3 LCAzODl9LA0KKwl7MSwgMTU4LCAzOTB9LA0KKwl7MSwgMTU5LCAzOTF9LA0KKw0KKwkvKiAzODAg Ki8NCisJezEsIDE2MCwgMzkyfSwNCisJezEsIDE2MSwgMzkzfSwNCisJezEsIDE2MiwgMzk0fSwN CisJezEsIDE2MywgMzk1fSwNCisJezEsIDE2NCwgMzk2fSwNCisJezEsIDE2NSwgMzk3fSwNCisJ ezEsIDE2NiwgMzk4fSwNCisJezEsIDE2NywgMzk5fSwNCisJezEsIDE2OCwgNDAwfSwNCisJezEs IDE2OSwgNDAxfSwNCisNCisJLyogMzkwICovDQorCXsxLCAxNzAsIDQwMn0sDQorCXsxLCAxNzEs IDQwM30sDQorCXsxLCAxNzIsIDQwNH0sDQorCXsxLCAxNzMsIDQwNX0sDQorCXsxLCAxNzQsIDQw Nn0sDQorCXsxLCAxNzUsIDQwN30sDQorCXsxLCAxNzYsIDQwOH0sDQorCXsxLCAxNzcsIDQwOX0s DQorCXsxLCAxNzgsIDQxMH0sDQorCXsxLCAxNzksIDQxMX0sDQorDQorCS8qIDQwMCAqLw0KKwl7 MSwgMTgwLCA0MTJ9LA0KKwl7MSwgMTgxLCA0MTN9LA0KKwl7MSwgMTgyLCA0MTR9LA0KKwl7MSwg MTgzLCA0MTV9LA0KKwl7MSwgMTg0LCA0MTZ9LA0KKwl7MSwgMTg1LCA0MTd9LA0KKwl7MSwgMTg2 LCA0MTh9LA0KKwl7MSwgMTg3LCA0MTl9LA0KKwl7MSwgMTg4LCA0MjB9LA0KKwl7MSwgMTg5LCA0 MjF9LA0KKw0KKwkvKiA0MTAgKi8NCisJezEsIDE5MCwgNDIyfSwNCisJezEsIDE5MSwgNDIzfSwN CisJezEsIDE5MiwgNDI0fSwNCisJezEsIDE5MywgNDI1fSwNCisJezEsIDE5NCwgNDI2fSwNCisJ ezEsIDE5NSwgNDI3fSwNCisJezEsIDE5NiwgNDI4fSwNCisJezEsIDE5NywgNDI5fSwNCisJezEs IDE5OCwgNDMwfSwNCisJezEsIDE5OSwgNDMxfSwNCisNCisJLyogNDIwICovDQorCXsxLCAyMDAs IDQzMn0sDQorCXsxLCAyMDEsIDQzM30sDQorCXsxLCAyMDIsIDQzNH0sDQorCXsxLCAyMDMsIDQz NX0sDQorCXsxLCAyMDQsIDQzNn0sDQorCXsxLCAyMDUsIDQzN30sDQorCXsxLCAyMDYsIDQzOH0s DQorCXsxLCAyMDcsIDQzOX0sDQorCXsxLCAyMDgsIDQ0MH0sDQorCXsxLCAyMDksIDQ0MX0sDQor DQorCS8qIDQzMCAqLw0KKwl7MSwgMjEwLCA0NDJ9LA0KKwl7MSwgMjExLCA0NDN9LA0KKwl7MSwg MjEyLCA0NDR9LA0KKwl7MSwgMjEzLCA0NDV9LA0KKwl7MSwgMjE0LCA0NDZ9LA0KKwl7MSwgMjE1 LCA0NDd9LA0KKwl7MSwgMjE2LCA0NDh9LA0KKwl7MSwgMjE3LCA0NDl9LA0KKwl7MSwgMjE4LCA0 NTB9LA0KKwl7MSwgMjE5LCA0NTF9LA0KKw0KKwkvKiA0NDAgKi8NCisJezEsIDIyMCwgNDUyfSwN CisJezEsIDIyMSwgNDUzfSwNCisJezEsIDIyMiwgNDU0fSwNCisJezEsIDIyMywgNDU1fSwNCisJ ezEsIDIyNCwgNDU2fSwNCisJezEsIDIyNSwgNDU3fSwNCisJezEsIDIyNiwgNDU4fSwNCisJezEs IDIyNywgNDU5fSwNCisJezEsIDIyOCwgNDYwfSwNCisJezEsIDIyOSwgNDYxfSwNCisNCisJLyog NDUwICovDQorCXsxLCAyMzAsIDQ2Mn0sDQorCXsxLCAyMzEsIDQ2M30sDQorCXsxLCAyMzIsIDQ2 NH0sDQorCXsxLCAyMzMsIDQ2NX0sDQorCXsxLCAyMzQsIDQ2Nn0sDQorCXsxLCAyMzUsIDQ2N30s DQorCXsxLCAyMzYsIDQ2OH0sDQorCXsxLCAyMzcsIDQ2OX0sDQorCXsxLCAyMzgsIDQ3MH0sDQor CXsxLCAyMzksIDQ3MX0sDQorDQorCS8qIDQ2MCAqLw0KKwl7MSwgMjQwLCA0NzJ9LA0KKwl7MSwg MjQxLCA0NzN9LA0KKwl7MSwgMjQyLCA0NzR9LA0KKwl7MSwgMjQzLCA0NzV9LA0KKwl7MSwgMjQ0 LCA0NzZ9LA0KKwl7MSwgMjQ1LCA0Nzd9LA0KKwl7MSwgMjQ2LCA0Nzh9LA0KKwl7LTEsIC0xLCA0 Nzl9LA0KKwl7LTEsIC0xLCA0ODB9LA0KKwl7LTEsIC0xLCA0ODF9LA0KKw0KKwkvKiA0NzAgKi8N CisJey0xLCAtMSwgNDgyfSwNCisJey0xLCAtMSwgNDgzfSwNCisJey0xLCAtMSwgNDg0fSwNCisJ ey0xLCAtMSwgNDg1fSwNCisJey0xLCAtMSwgNDg2fSwNCisJey0xLCAtMSwgNDg3fSwNCisJey0x LCAtMSwgNDg4fSwNCisJey0xLCAtMSwgNDg5fSwNCisJey0xLCAtMSwgNDkwfSwNCisJey0xLCAt MSwgNDkxfSwNCisNCisJLyogNDgwICovDQorCXstMSwgLTEsIDQ5Mn0sDQorCXstMSwgLTEsIDQ5 M30sDQorCXstMSwgLTEsIDQ5NH0sDQorCXstMSwgLTEsIDQ5NX0sDQorCXstMSwgLTEsIDQ5Nn0s DQorCXstMSwgLTEsIDQ5N30sDQorCXstMSwgLTEsIDQ5OH0sDQorCXstMSwgLTEsIDQ5OX0sDQor CXstMSwgLTEsIDUwMH0sDQorCXstMSwgLTEsIDUwMX0sDQorDQorCS8qIDQ5MCAqLw0KKwl7LTEs IC0xLCA1MDJ9LA0KKwl7LTEsIC0xLCA1MDN9LA0KKwl7LTEsIC0xLCA1MDR9LA0KKwl7LTEsIC0x LCA1MDV9LA0KKwl7LTEsIC0xLCA1MDZ9LA0KKwl7LTEsIC0xLCA1MDd9LA0KKwl7LTEsIC0xLCA1 MDh9LA0KKwl7LTEsIC0xLCA1MDl9LA0KKwl7LTEsIC0xLCA1MTB9LA0KKw0KK307DQorDQorc3Ry dWN0IG10a19kZXZhcGNfdmlvX2luZm8gew0KKwlib29sIHJlYWQ7DQorCWJvb2wgd3JpdGU7DQor CXUzMiB2aW9fYWRkcjsNCisJdTMyIHZpb19hZGRyX2hpZ2g7DQorCXUzMiBtYXN0ZXJfaWQ7DQor CXUzMiBkb21haW5faWQ7DQorfTsNCisNCitzdHJ1Y3QgbXRrX2RldmFwY192aW9fZGJnc19kZXNj IHsNCisJdTMyIG1hc2s7DQorCXUzMiBzdGFydF9iaXQ7DQorfTsNCisNCitzdHJ1Y3QgbXRrX2Rl dmFwY19jb250ZXh0IHsNCisJdTggc2xhdmVfdHlwZV9udW07DQorCXZvaWQgX19pb21lbSAqKmRl dmFwY19wZF9iYXNlOw0KKwljb25zdCBzdHJ1Y3QgbXRrX2RldmljZV9pbmZvICoqZGV2aWNlX2lu Zm87DQorCXN0cnVjdCBtdGtfZGV2YXBjX3Zpb19pbmZvICp2aW9faW5mbzsNCisJc3RydWN0IG10 a19kZXZhcGNfdmlvX2RiZ3NfZGVzYyAqdmlvX2RiZ3NfZGVzYzsNCisJdTMyICpwZHNfb2Zmc2V0 Ow0KK307DQorDQorI2VuZGlmIC8qIF9fTVRLX0RFVkFQQ19IX18gKi8NCi0tIA0KMS43LjkuNQ0K 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.7 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C4CA7C433E0 for ; Thu, 9 Jul 2020 09:13:15 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 86BBF206C3 for ; Thu, 9 Jul 2020 09:13:15 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="c4NQQSq6"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="Cb85n6SR" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 86BBF206C3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-ID:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=+4d997UAarc0MBMd7DRPW7H0y4F3IherXbtjxUUbhGE=; b=c4NQQSq6WWxRiXIf1a78xV34V iG1xc9zmudZo2t19/eyZ5kTkqyE8IiPOeqwvEUpFiL4t7DbGqyWktJtSdcuvngORkhIeDRSpXgBJ1 Ky9JWjMtnMRtoPmnfMJe9PZ78DFnyk9XEHL/P28T6QZTcHl0H/96RLxBrmFNObExWNuqq27C+JJP1 lhOlbHXmA0c0jlycixKEaxGhr3NkYyT5933hMrY33NOLxo2fR6PG7IGTO95Y+r8y+TYDKjMuiDgVJ 8jO3oD4hGHczIMLKkPSgVacl6s4vbnnSDVHg7+TfICmTdTVTv6TlIJJG50GwbrSp7mcq+6fQUK7NU PTx/S1MEw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jtSbz-0002ic-W8; Thu, 09 Jul 2020 09:13:01 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jtSbT-0002RM-LH; Thu, 09 Jul 2020 09:12:30 +0000 X-UUID: e8910e14e9ca498bb235633d41520a91-20200709 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=uEIodGb+H0SrBqh8VNgfTXkSpyd8DbLFMTrEpDE4eVA=; b=Cb85n6SRfM7l5AP9Kod9cb4gFsFaQaQQk+7QKqmUkVd/txieafbi6bgT+wLNSWO05k4UB5YXGGRaY0eczPcvdYH3C09Te/DQodM2Nx2oq6AQxkPBexoMPyVjCD+yjyMyuuO/N6I9LCuprPNh1xTL+LUwIN1srLq0z0da6+hPy3c=; X-UUID: e8910e14e9ca498bb235633d41520a91-20200709 Received: from mtkcas68.mediatek.inc [(172.29.94.19)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLS) with ESMTP id 344245934; Thu, 09 Jul 2020 01:12:10 -0800 Received: from MTKMBS01N1.mediatek.inc (172.21.101.68) by MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 9 Jul 2020 02:12:17 -0700 Received: from mtkcas08.mediatek.inc (172.21.101.126) by mtkmbs01n1.mediatek.inc (172.21.101.68) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 9 Jul 2020 17:12:16 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas08.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 9 Jul 2020 17:12:18 +0800 From: Neal Liu To: Rob Herring , Matthias Brugger Subject: [PATCH v2 2/2] soc: mediatek: add mtk-devapc driver Date: Thu, 9 Jul 2020 17:12:07 +0800 Message-ID: <1594285927-1840-3-git-send-email-neal.liu@mediatek.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1594285927-1840-1-git-send-email-neal.liu@mediatek.com> References: <1594285927-1840-1-git-send-email-neal.liu@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200709_051228_088480_044CABEF X-CRM114-Status: GOOD ( 24.12 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, wsd_upstream@mediatek.com, lkml , linux-mediatek@lists.infradead.org, Neal Liu , linux-arm-kernel@lists.infradead.org Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org MediaTek bus fabric provides TrustZone security support and data protection to prevent slaves from being accessed by unexpected masters. The security violation is logged and sent to the processor for further analysis or countermeasures. Any occurrence of security violation would raise an interrupt, and it will be handled by mtk-devapc driver. The violation information is printed in order to find the murderer. Signed-off-by: Neal Liu --- drivers/soc/mediatek/Kconfig | 9 + drivers/soc/mediatek/Makefile | 1 + drivers/soc/mediatek/mtk-devapc.c | 466 ++++++++++++++++++++++++++ drivers/soc/mediatek/mtk-devapc.h | 670 +++++++++++++++++++++++++++++++++++++ 4 files changed, 1146 insertions(+) create mode 100644 drivers/soc/mediatek/mtk-devapc.c create mode 100644 drivers/soc/mediatek/mtk-devapc.h diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig index 59a56cd..1177c98 100644 --- a/drivers/soc/mediatek/Kconfig +++ b/drivers/soc/mediatek/Kconfig @@ -17,6 +17,15 @@ config MTK_CMDQ time limitation, such as updating display configuration during the vblank. +config MTK_DEVAPC + tristate "Mediatek Device APC Support" + help + Say yes here to enable support for Mediatek Device APC driver. + This driver is mainly used to handle the violation which catches + unexpected transaction. + The violation information is logged for further analysis or + countermeasures. + config MTK_INFRACFG bool "MediaTek INFRACFG Support" select REGMAP diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile index 01f9f87..abfd4ba 100644 --- a/drivers/soc/mediatek/Makefile +++ b/drivers/soc/mediatek/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o +obj-$(CONFIG_MTK_DEVAPC) += mtk-devapc.o obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c new file mode 100644 index 0000000..11fa366 --- /dev/null +++ b/drivers/soc/mediatek/mtk-devapc.c @@ -0,0 +1,466 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include "mtk-devapc.h" + +/* + * mtk_devapc_pd_get - get devapc pd_types of register address. + * + * Returns the value of reg addr + */ +static void __iomem *mtk_devapc_pd_get(struct mtk_devapc_context *devapc_ctx, + int slave_type, + enum DEVAPC_PD_REG_TYPE pd_reg_type, + u32 reg_idx) +{ + void __iomem *reg; + + reg = devapc_ctx->devapc_pd_base[slave_type] + + devapc_ctx->pds_offset[pd_reg_type]; + + if (pd_reg_type == VIO_MASK || pd_reg_type == VIO_STA) + reg += 0x4 * reg_idx; + + return reg; +} + +static int get_vio_slave_num(int slave_type) +{ + if (slave_type == 0) + return ARRAY_SIZE(mtk_devices_infra); + + return 0; +} + +static u32 get_shift_group(struct mtk_devapc_context *devapc_ctx, + int slave_type, int vio_idx) +{ + u32 vio_shift_sta; + void __iomem *reg; + int bit; + + reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_SHIFT_STA, 0); + vio_shift_sta = readl(reg); + + for (bit = 0; bit < 32; bit++) { + if ((vio_shift_sta >> bit) & 0x1) + break; + } + + return bit; +} + +static int check_vio_mask_sta(struct mtk_devapc_context *devapc_ctx, + int slave_type, u32 module, int pd_reg_type) +{ + u32 reg_index, reg_offset; + void __iomem *reg; + u32 value; + + VIO_MASK_STA_REG_GET(module); + + reg = mtk_devapc_pd_get(devapc_ctx, slave_type, pd_reg_type, reg_index); + value = readl(reg); + + return ((value >> reg_offset) & 0x1); +} + +static int check_vio_mask(struct mtk_devapc_context *devapc_ctx, int slave_type, + u32 module) +{ + return check_vio_mask_sta(devapc_ctx, slave_type, module, VIO_MASK); +} + +static int check_vio_status(struct mtk_devapc_context *devapc_ctx, + int slave_type, u32 module) +{ + return check_vio_mask_sta(devapc_ctx, slave_type, module, VIO_STA); +} + +static void clear_vio_status(struct mtk_devapc_context *devapc_ctx, + int slave_type, u32 module) +{ + u32 reg_index, reg_offset; + void __iomem *reg; + + VIO_MASK_STA_REG_GET(module); + + reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_STA, reg_index); + writel(0x1 << reg_offset, reg); + + if (check_vio_status(devapc_ctx, slave_type, module)) + pr_err(PFX "%s: Clear failed, slave_type:0x%x, module_index:0x%x\n", + __func__, slave_type, module); +} + +static void mask_module_irq(struct mtk_devapc_context *devapc_ctx, + int slave_type, u32 module, bool mask) +{ + u32 reg_index, reg_offset; + void __iomem *reg; + u32 value; + + VIO_MASK_STA_REG_GET(module); + + reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_MASK, reg_index); + + value = readl(reg); + if (mask) + value |= (0x1 << reg_offset); + else + value &= ~(0x1 << reg_offset); + + writel(value, reg); +} + +#define TIMEOUT_MS 10000 + +static int read_poll_timeout(void __iomem *addr, u32 mask) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS); + + do { + if (readl_relaxed(addr) & mask) + return 0; + + } while (!time_after(jiffies, timeout)); + + return (readl_relaxed(addr) & mask) ? 0 : -ETIMEDOUT; +} + +/* + * sync_vio_dbg - start to get violation information by selecting violation + * group and enable violation shift. + * + * Returns sync done or not + */ +static u32 sync_vio_dbg(struct mtk_devapc_context *devapc_ctx, int slave_type, + u32 shift_bit) +{ + void __iomem *pd_vio_shift_sta_reg; + void __iomem *pd_vio_shift_sel_reg; + void __iomem *pd_vio_shift_con_reg; + u32 sync_done = 0; + + pd_vio_shift_sta_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_STA, 0); + pd_vio_shift_sel_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_SEL, 0); + pd_vio_shift_con_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_CON, 0); + + writel(0x1 << shift_bit, pd_vio_shift_sel_reg); + writel(0x1, pd_vio_shift_con_reg); + + if (!read_poll_timeout(pd_vio_shift_con_reg, 0x2)) + sync_done = 1; + else + pr_err(PFX "%s: Shift violation info failed\n", __func__); + + /* Disable shift mechanism */ + writel(0x0, pd_vio_shift_con_reg); + writel(0x0, pd_vio_shift_sel_reg); + writel(0x1 << shift_bit, pd_vio_shift_sta_reg); + + return sync_done; +} + +static void devapc_vio_info_print(struct mtk_devapc_context *devapc_ctx) +{ + struct mtk_devapc_vio_info *vio_info = devapc_ctx->vio_info; + + /* Print violation information */ + if (vio_info->write) + pr_info(PFX "Write Violation\n"); + else if (vio_info->read) + pr_info(PFX "Read Violation\n"); + + pr_info(PFX "%s%x, %s%x, %s%x, %s%x\n", + "Vio Addr:0x", vio_info->vio_addr, + "High:0x", vio_info->vio_addr_high, + "Bus ID:0x", vio_info->master_id, + "Dom ID:0x", vio_info->domain_id); +} + +static void devapc_extract_vio_dbg(struct mtk_devapc_context *devapc_ctx, + int slave_type) +{ + void __iomem *vio_dbg0_reg, *vio_dbg1_reg; + struct mtk_devapc_vio_dbgs_desc *vio_dbgs; + struct mtk_devapc_vio_info *vio_info; + u32 dbg0; + + vio_dbg0_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_DBG0, 0); + vio_dbg1_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_DBG1, 0); + + vio_dbgs = devapc_ctx->vio_dbgs_desc; + vio_info = devapc_ctx->vio_info; + + /* Extract violation information */ + dbg0 = readl(vio_dbg0_reg); + vio_info->vio_addr = readl(vio_dbg1_reg); + + vio_info->master_id = (dbg0 & vio_dbgs[MSTID].mask) >> + vio_dbgs[MSTID].start_bit; + vio_info->domain_id = (dbg0 & vio_dbgs[DMNID].mask) >> + vio_dbgs[DMNID].start_bit; + vio_info->write = ((dbg0 & vio_dbgs[VIO_W].mask) >> + vio_dbgs[VIO_W].start_bit) == 1; + vio_info->read = ((dbg0 & vio_dbgs[VIO_R].mask) >> + vio_dbgs[VIO_R].start_bit) == 1; + vio_info->vio_addr_high = (dbg0 & vio_dbgs[ADDR_H].mask) >> + vio_dbgs[ADDR_H].start_bit; + + devapc_vio_info_print(devapc_ctx); +} + +/* + * mtk_devapc_dump_vio_dbg - shift & dump the violation debug information. + */ +static bool mtk_devapc_dump_vio_dbg(struct mtk_devapc_context *devapc_ctx, + int slave_type, int *vio_idx) +{ + const struct mtk_device_info **device_info; + u32 shift_bit; + int i; + + device_info = devapc_ctx->device_info; + + for (i = 0; i < get_vio_slave_num(slave_type); i++) { + *vio_idx = device_info[slave_type][i].vio_index; + + if (check_vio_mask(devapc_ctx, slave_type, *vio_idx)) + continue; + + if (!check_vio_status(devapc_ctx, slave_type, *vio_idx)) + continue; + + shift_bit = get_shift_group(devapc_ctx, slave_type, *vio_idx); + + if (!sync_vio_dbg(devapc_ctx, slave_type, shift_bit)) + continue; + + devapc_extract_vio_dbg(devapc_ctx, slave_type); + + return true; + } + + return false; +} + +/* + * devapc_violation_irq - the devapc Interrupt Service Routine (ISR) will dump + * violation information including which master violates + * access slave. + */ +static irqreturn_t devapc_violation_irq(int irq_number, + struct mtk_devapc_context *devapc_ctx) +{ + const struct mtk_device_info **device_info; + int slave_type_num; + int vio_idx = -1; + int slave_type; + + slave_type_num = devapc_ctx->slave_type_num; + device_info = devapc_ctx->device_info; + + for (slave_type = 0; slave_type < slave_type_num; slave_type++) { + if (!mtk_devapc_dump_vio_dbg(devapc_ctx, slave_type, &vio_idx)) + continue; + + /* Ensure that violation info are written before + * further operations + */ + smp_mb(); + + mask_module_irq(devapc_ctx, slave_type, vio_idx, true); + + clear_vio_status(devapc_ctx, slave_type, vio_idx); + + mask_module_irq(devapc_ctx, slave_type, vio_idx, false); + } + + return IRQ_HANDLED; +} + +/* + * start_devapc - initialize devapc status and start receiving interrupt + * while devapc violation is triggered. + */ +static void start_devapc(struct mtk_devapc_context *devapc_ctx) +{ + const struct mtk_device_info **device_info; + void __iomem *pd_vio_shift_sta_reg; + void __iomem *pd_apc_con_reg; + u32 vio_shift_sta; + int slave_type, slave_type_num; + int i, vio_idx; + + device_info = devapc_ctx->device_info; + slave_type_num = devapc_ctx->slave_type_num; + + for (slave_type = 0; slave_type < slave_type_num; slave_type++) { + pd_apc_con_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + APC_CON, 0); + pd_vio_shift_sta_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_STA, 0); + if (!pd_apc_con_reg || !pd_vio_shift_sta_reg) + return; + + /* Clear devapc violation status */ + writel(BIT(31), pd_apc_con_reg); + + /* Clear violation shift status */ + vio_shift_sta = readl(pd_vio_shift_sta_reg); + if (vio_shift_sta) + writel(vio_shift_sta, pd_vio_shift_sta_reg); + + /* Clear slave violation status */ + for (i = 0; i < get_vio_slave_num(slave_type); i++) { + vio_idx = device_info[slave_type][i].vio_index; + + clear_vio_status(devapc_ctx, slave_type, vio_idx); + + mask_module_irq(devapc_ctx, slave_type, vio_idx, false); + } + } +} + +static int mtk_devapc_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct mtk_devapc_context *devapc_ctx; + struct clk *devapc_infra_clk; + u32 vio_dbgs_num, pds_num; + u8 slave_type_num; + u32 devapc_irq; + size_t size; + int i, ret; + + if (IS_ERR(node)) + return -ENODEV; + + devapc_ctx = devm_kzalloc(&pdev->dev, sizeof(struct mtk_devapc_context), + GFP_KERNEL); + if (!devapc_ctx) + return -ENOMEM; + + if (of_property_read_u8(node, "mediatek-slv_type_num", &slave_type_num)) + return -ENXIO; + + devapc_ctx->slave_type_num = slave_type_num; + + size = slave_type_num * sizeof(void *); + devapc_ctx->devapc_pd_base = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!devapc_ctx->devapc_pd_base) + return -ENOMEM; + + size = slave_type_num * sizeof(struct mtk_device_info *); + devapc_ctx->device_info = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!devapc_ctx->device_info) + return -ENOMEM; + + for (i = 0; i < slave_type_num; i++) { + devapc_ctx->devapc_pd_base[i] = of_iomap(node, i); + if (!devapc_ctx->devapc_pd_base[i]) + return -EINVAL; + + if (i == 0) + devapc_ctx->device_info[i] = mtk_devices_infra; + } + + size = sizeof(struct mtk_devapc_vio_info); + devapc_ctx->vio_info = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!devapc_ctx->vio_info) + return -ENOMEM; + + vio_dbgs_num = of_property_count_u32_elems(node, "mediatek-vio_dbgs"); + if (vio_dbgs_num <= 0) + return -ENXIO; + + size = (vio_dbgs_num / 2) * sizeof(struct mtk_devapc_vio_dbgs_desc); + devapc_ctx->vio_dbgs_desc = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!devapc_ctx->vio_dbgs_desc) + return -ENOMEM; + + for (i = 0; i < vio_dbgs_num / 2; i++) { + if (of_property_read_u32_index(node, "mediatek-vio_dbgs", + i * 2, + &devapc_ctx->vio_dbgs_desc[i].mask)) + return -ENXIO; + + if (of_property_read_u32_index(node, "mediatek-vio_dbgs", + (i * 2) + 1, + &devapc_ctx->vio_dbgs_desc[i].start_bit)) + return -ENXIO; + } + + pds_num = of_property_count_u32_elems(node, "mediatek-pds_offset"); + if (pds_num <= 0) + return -ENXIO; + + size = pds_num * sizeof(u32); + devapc_ctx->pds_offset = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!devapc_ctx->pds_offset) + return -ENOMEM; + + for (i = 0; i < pds_num; i++) { + if (of_property_read_u32_index(node, "mediatek-pds_offset", i, + &devapc_ctx->pds_offset[i])) + return -ENXIO; + } + + devapc_irq = irq_of_parse_and_map(node, 0); + if (!devapc_irq) + return -EINVAL; + + devapc_infra_clk = devm_clk_get(&pdev->dev, "devapc-infra-clock"); + if (IS_ERR(devapc_infra_clk)) + return -EINVAL; + + if (clk_prepare_enable(devapc_infra_clk)) + return -EINVAL; + + start_devapc(devapc_ctx); + + ret = devm_request_irq(&pdev->dev, devapc_irq, + (irq_handler_t)devapc_violation_irq, + IRQF_TRIGGER_NONE, "devapc", devapc_ctx); + if (ret) + return ret; + + return 0; +} + +static int mtk_devapc_remove(struct platform_device *dev) +{ + return 0; +} + +static const struct of_device_id mtk_devapc_dt_match[] = { + { .compatible = "mediatek,mt6779-devapc" }, + {}, +}; + +static struct platform_driver mtk_devapc_driver = { + .probe = mtk_devapc_probe, + .remove = mtk_devapc_remove, + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = mtk_devapc_dt_match, + }, +}; + +module_platform_driver(mtk_devapc_driver); + +MODULE_DESCRIPTION("Mediatek Device APC Driver"); +MODULE_AUTHOR("Neal Liu "); +MODULE_LICENSE("GPL"); diff --git a/drivers/soc/mediatek/mtk-devapc.h b/drivers/soc/mediatek/mtk-devapc.h new file mode 100644 index 0000000..ab2cb14 --- /dev/null +++ b/drivers/soc/mediatek/mtk-devapc.h @@ -0,0 +1,670 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 MediaTek Inc. + */ + +#ifndef __MTK_DEVAPC_H__ +#define __MTK_DEVAPC_H__ + +#define PFX "[DEVAPC]: " + +#define VIO_MASK_STA_REG_GET(m) \ +({ \ + typeof(m) (_m) = (m); \ + reg_index = _m / 32; \ + reg_offset = _m % 32; \ +}) + +enum DEVAPC_PD_REG_TYPE { + VIO_MASK = 0, + VIO_STA, + VIO_DBG0, + VIO_DBG1, + APC_CON, + VIO_SHIFT_STA, + VIO_SHIFT_SEL, + VIO_SHIFT_CON, + PD_REG_TYPE_NUM, +}; + +enum DEVAPC_VIO_DBGS_TYPE { + MSTID = 0, + DMNID, + VIO_W, + VIO_R, + ADDR_H, +}; + +struct mtk_device_info { + int sys_index; + int ctrl_index; + int vio_index; +}; + +static struct mtk_device_info mtk_devices_infra[] = { + /* sys_idx, ctrl_idx, vio_idx */ + /* 0 */ + {0, 0, 0}, + {0, 1, 1}, + {0, 2, 2}, + {0, 3, 3}, + {0, 4, 4}, + {0, 5, 5}, + {0, 6, 6}, + {0, 7, 7}, + {0, 8, 8}, + {0, 9, 9}, + + /* 10 */ + {0, 10, 10}, + {0, 11, 11}, + {0, 12, 12}, + {0, 13, 13}, + {0, 14, 14}, + {0, 15, 15}, + {0, 16, 16}, + {0, 17, 17}, + {0, 18, 18}, + {0, 19, 19}, + + /* 20 */ + {0, 20, 20}, + {0, 21, 21}, + {0, 22, 22}, + {0, 23, 23}, + {0, 24, 24}, + {0, 25, 25}, + {0, 26, 26}, + {0, 27, 27}, + {0, 28, 28}, + {0, 29, 29}, + + /* 30 */ + {0, 30, 30}, + {0, 31, 31}, + {0, 32, 32}, + {0, 33, 77}, + {0, 34, 78}, + {0, 35, 79}, + {0, 35, 80}, + {0, 37, 37}, + {0, 38, 38}, + {0, 39, 39}, + + /* 40 */ + {0, 40, 40}, + {0, 41, 41}, + {0, 42, 42}, + {0, 43, 43}, + {0, 44, 44}, + {0, 45, 45}, + {0, 46, 46}, + {0, 47, 47}, + {0, 48, 48}, + {0, 49, 49}, + + /* 50 */ + {0, 50, 50}, + {0, 51, 51}, + {0, 52, 52}, + {0, 53, 53}, + {0, 54, 54}, + {0, 55, 55}, + {0, 56, 56}, + {0, 57, 57}, + {0, 58, 58}, + {0, 59, 59}, + + /* 60 */ + {0, 60, 60}, + {0, 61, 61}, + {0, 62, 62}, + {0, 63, 63}, + {0, 64, 64}, + {0, 65, 70}, + {0, 66, 71}, + {0, 67, 72}, + {0, 68, 73}, + {0, 70, 81}, + + /* 70 */ + {0, 71, 82}, + {0, 72, 83}, + {0, 73, 84}, + {0, 74, 85}, + {0, 75, 86}, + {0, 76, 87}, + {0, 77, 88}, + {0, 78, 89}, + {0, 79, 90}, + {0, 80, 91}, + + /* 80 */ + {0, 81, 92}, + {0, 82, 93}, + {0, 83, 94}, + {0, 84, 95}, + {0, 85, 96}, + {0, 86, 97}, + {0, 87, 98}, + {0, 88, 99}, + {0, 89, 100}, + {0, 90, 101}, + + /* 90 */ + {0, 91, 102}, + {0, 92, 103}, + {0, 93, 104}, + {0, 94, 105}, + {0, 95, 106}, + {0, 96, 107}, + {0, 97, 108}, + {0, 98, 109}, + {0, 110, 110}, + {0, 111, 111}, + + /* 100 */ + {0, 112, 112}, + {0, 113, 113}, + {0, 114, 114}, + {0, 115, 115}, + {0, 116, 116}, + {0, 117, 117}, + {0, 118, 118}, + {0, 119, 119}, + {0, 120, 120}, + {0, 121, 121}, + + /* 110 */ + {0, 122, 122}, + {0, 123, 123}, + {0, 124, 124}, + {0, 125, 125}, + {0, 126, 126}, + {0, 127, 127}, + {0, 128, 128}, + {0, 129, 129}, + {0, 130, 130}, + {0, 131, 131}, + + /* 120 */ + {0, 132, 132}, + {0, 133, 133}, + {0, 134, 134}, + {0, 135, 135}, + {0, 136, 136}, + {0, 137, 137}, + {0, 138, 138}, + {0, 139, 139}, + {0, 140, 140}, + {0, 141, 141}, + + /* 130 */ + {0, 142, 142}, + {0, 143, 143}, + {0, 144, 144}, + {0, 145, 145}, + {0, 146, 146}, + {0, 147, 147}, + {0, 148, 148}, + {0, 149, 149}, + {0, 150, 150}, + {0, 151, 151}, + + /* 140 */ + {0, 152, 152}, + {0, 153, 153}, + {0, 154, 154}, + {0, 155, 155}, + {0, 156, 156}, + {0, 157, 157}, + {0, 158, 158}, + {0, 159, 159}, + {0, 160, 160}, + {0, 161, 161}, + + /* 150 */ + {0, 162, 162}, + {0, 163, 163}, + {0, 164, 164}, + {0, 165, 165}, + {0, 166, 166}, + {0, 167, 167}, + {0, 168, 168}, + {0, 169, 169}, + {0, 170, 170}, + {0, 171, 171}, + + /* 160 */ + {0, 172, 172}, + {0, 173, 173}, + {0, 174, 174}, + {0, 175, 175}, + {0, 176, 176}, + {0, 177, 177}, + {0, 178, 178}, + {0, 179, 179}, + {0, 180, 180}, + {0, 181, 181}, + + /* 170 */ + {0, 182, 182}, + {0, 183, 183}, + {0, 184, 184}, + {0, 185, 185}, + {0, 186, 186}, + {0, 187, 187}, + {0, 188, 188}, + {0, 189, 189}, + {0, 190, 190}, + {0, 191, 191}, + + /* 180 */ + {0, 192, 192}, + {0, 193, 193}, + {0, 194, 194}, + {0, 195, 195}, + {0, 196, 196}, + {0, 197, 197}, + {0, 198, 198}, + {0, 199, 199}, + {0, 200, 200}, + {0, 201, 201}, + + /* 190 */ + {0, 202, 202}, + {0, 203, 203}, + {0, 204, 204}, + {0, 205, 205}, + {0, 206, 206}, + {0, 207, 207}, + {0, 208, 208}, + {0, 209, 209}, + {0, 210, 210}, + {0, 211, 211}, + + /* 200 */ + {0, 212, 212}, + {0, 213, 213}, + {0, 214, 214}, + {0, 215, 215}, + {0, 216, 216}, + {0, 217, 217}, + {0, 218, 218}, + {0, 219, 219}, + {0, 220, 220}, + {0, 221, 221}, + + /* 210 */ + {0, 222, 222}, + {0, 223, 223}, + {0, 224, 224}, + {0, 225, 225}, + {0, 226, 226}, + {0, 227, 227}, + {0, 228, 228}, + {0, 229, 229}, + {0, 230, 230}, + {0, 231, 231}, + + /* 220 */ + {1, 0, 232}, + {1, 1, 233}, + {1, 2, 234}, + {1, 3, 235}, + {1, 4, 236}, + {1, 5, 237}, + {1, 6, 238}, + {1, 7, 239}, + {1, 8, 240}, + {1, 9, 241}, + + /* 230 */ + {1, 10, 242}, + {1, 11, 243}, + {1, 12, 244}, + {1, 13, 245}, + {1, 14, 246}, + {1, 15, 247}, + {1, 16, 248}, + {1, 17, 249}, + {1, 18, 250}, + {1, 19, 251}, + + /* 240 */ + {1, 20, 252}, + {1, 21, 253}, + {1, 22, 254}, + {1, 23, 255}, + {1, 24, 256}, + {1, 25, 257}, + {1, 26, 258}, + {1, 27, 259}, + {1, 28, 260}, + {1, 29, 261}, + + /* 250 */ + {1, 30, 262}, + {1, 31, 263}, + {1, 32, 264}, + {1, 33, 265}, + {1, 34, 266}, + {1, 35, 267}, + {1, 36, 268}, + {1, 37, 269}, + {1, 38, 270}, + {1, 39, 271}, + + /* 260 */ + {1, 40, 272}, + {1, 41, 273}, + {1, 42, 274}, + {1, 43, 275}, + {1, 44, 276}, + {1, 45, 277}, + {1, 46, 278}, + {1, 47, 279}, + {1, 48, 280}, + {1, 49, 281}, + + /* 270 */ + {1, 50, 282}, + {1, 51, 283}, + {1, 52, 284}, + {1, 53, 285}, + {1, 54, 286}, + {1, 55, 287}, + {1, 56, 288}, + {1, 57, 289}, + {1, 58, 290}, + {1, 59, 291}, + + /* 280 */ + {1, 60, 292}, + {1, 61, 293}, + {1, 62, 294}, + {1, 63, 295}, + {1, 64, 296}, + {1, 65, 297}, + {1, 66, 298}, + {1, 67, 299}, + {1, 68, 300}, + {1, 69, 301}, + + /* 290 */ + {1, 70, 302}, + {1, 71, 303}, + {1, 72, 304}, + {1, 73, 305}, + {1, 74, 306}, + {1, 75, 307}, + {1, 76, 308}, + {1, 77, 309}, + {1, 78, 310}, + {1, 79, 311}, + + /* 300 */ + {1, 80, 312}, + {1, 81, 313}, + {1, 82, 314}, + {1, 83, 315}, + {1, 84, 316}, + {1, 85, 317}, + {1, 86, 318}, + {1, 87, 319}, + {1, 88, 320}, + {1, 89, 321}, + + /* 310 */ + {1, 90, 322}, + {1, 91, 323}, + {1, 92, 324}, + {1, 93, 325}, + {1, 94, 326}, + {1, 95, 327}, + {1, 96, 328}, + {1, 97, 329}, + {1, 98, 330}, + {1, 99, 331}, + + /* 320 */ + {1, 100, 332}, + {1, 101, 333}, + {1, 102, 334}, + {1, 103, 335}, + {1, 104, 336}, + {1, 105, 337}, + {1, 106, 338}, + {1, 107, 339}, + {1, 108, 340}, + {1, 109, 341}, + + /* 330 */ + {1, 110, 342}, + {1, 111, 343}, + {1, 112, 344}, + {1, 113, 345}, + {1, 114, 346}, + {1, 115, 347}, + {1, 116, 348}, + {1, 117, 349}, + {1, 118, 350}, + {1, 119, 351}, + + /* 340 */ + {1, 120, 352}, + {1, 121, 353}, + {1, 122, 354}, + {1, 123, 355}, + {1, 124, 356}, + {1, 125, 357}, + {1, 126, 358}, + {1, 127, 359}, + {1, 128, 360}, + {1, 129, 361}, + + /* 350 */ + {1, 130, 362}, + {1, 131, 363}, + {1, 132, 364}, + {1, 133, 365}, + {1, 134, 366}, + {1, 135, 367}, + {1, 136, 368}, + {1, 137, 369}, + {1, 138, 370}, + {1, 139, 371}, + + /* 360 */ + {1, 140, 372}, + {1, 141, 373}, + {1, 142, 374}, + {1, 143, 375}, + {1, 144, 376}, + {1, 145, 377}, + {1, 146, 378}, + {1, 147, 379}, + {1, 148, 380}, + {1, 149, 381}, + + /* 370 */ + {1, 150, 382}, + {1, 151, 383}, + {1, 152, 384}, + {1, 153, 385}, + {1, 154, 386}, + {1, 155, 387}, + {1, 156, 388}, + {1, 157, 389}, + {1, 158, 390}, + {1, 159, 391}, + + /* 380 */ + {1, 160, 392}, + {1, 161, 393}, + {1, 162, 394}, + {1, 163, 395}, + {1, 164, 396}, + {1, 165, 397}, + {1, 166, 398}, + {1, 167, 399}, + {1, 168, 400}, + {1, 169, 401}, + + /* 390 */ + {1, 170, 402}, + {1, 171, 403}, + {1, 172, 404}, + {1, 173, 405}, + {1, 174, 406}, + {1, 175, 407}, + {1, 176, 408}, + {1, 177, 409}, + {1, 178, 410}, + {1, 179, 411}, + + /* 400 */ + {1, 180, 412}, + {1, 181, 413}, + {1, 182, 414}, + {1, 183, 415}, + {1, 184, 416}, + {1, 185, 417}, + {1, 186, 418}, + {1, 187, 419}, + {1, 188, 420}, + {1, 189, 421}, + + /* 410 */ + {1, 190, 422}, + {1, 191, 423}, + {1, 192, 424}, + {1, 193, 425}, + {1, 194, 426}, + {1, 195, 427}, + {1, 196, 428}, + {1, 197, 429}, + {1, 198, 430}, + {1, 199, 431}, + + /* 420 */ + {1, 200, 432}, + {1, 201, 433}, + {1, 202, 434}, + {1, 203, 435}, + {1, 204, 436}, + {1, 205, 437}, + {1, 206, 438}, + {1, 207, 439}, + {1, 208, 440}, + {1, 209, 441}, + + /* 430 */ + {1, 210, 442}, + {1, 211, 443}, + {1, 212, 444}, + {1, 213, 445}, + {1, 214, 446}, + {1, 215, 447}, + {1, 216, 448}, + {1, 217, 449}, + {1, 218, 450}, + {1, 219, 451}, + + /* 440 */ + {1, 220, 452}, + {1, 221, 453}, + {1, 222, 454}, + {1, 223, 455}, + {1, 224, 456}, + {1, 225, 457}, + {1, 226, 458}, + {1, 227, 459}, + {1, 228, 460}, + {1, 229, 461}, + + /* 450 */ + {1, 230, 462}, + {1, 231, 463}, + {1, 232, 464}, + {1, 233, 465}, + {1, 234, 466}, + {1, 235, 467}, + {1, 236, 468}, + {1, 237, 469}, + {1, 238, 470}, + {1, 239, 471}, + + /* 460 */ + {1, 240, 472}, + {1, 241, 473}, + {1, 242, 474}, + {1, 243, 475}, + {1, 244, 476}, + {1, 245, 477}, + {1, 246, 478}, + {-1, -1, 479}, + {-1, -1, 480}, + {-1, -1, 481}, + + /* 470 */ + {-1, -1, 482}, + {-1, -1, 483}, + {-1, -1, 484}, + {-1, -1, 485}, + {-1, -1, 486}, + {-1, -1, 487}, + {-1, -1, 488}, + {-1, -1, 489}, + {-1, -1, 490}, + {-1, -1, 491}, + + /* 480 */ + {-1, -1, 492}, + {-1, -1, 493}, + {-1, -1, 494}, + {-1, -1, 495}, + {-1, -1, 496}, + {-1, -1, 497}, + {-1, -1, 498}, + {-1, -1, 499}, + {-1, -1, 500}, + {-1, -1, 501}, + + /* 490 */ + {-1, -1, 502}, + {-1, -1, 503}, + {-1, -1, 504}, + {-1, -1, 505}, + {-1, -1, 506}, + {-1, -1, 507}, + {-1, -1, 508}, + {-1, -1, 509}, + {-1, -1, 510}, + +}; + +struct mtk_devapc_vio_info { + bool read; + bool write; + u32 vio_addr; + u32 vio_addr_high; + u32 master_id; + u32 domain_id; +}; + +struct mtk_devapc_vio_dbgs_desc { + u32 mask; + u32 start_bit; +}; + +struct mtk_devapc_context { + u8 slave_type_num; + void __iomem **devapc_pd_base; + const struct mtk_device_info **device_info; + struct mtk_devapc_vio_info *vio_info; + struct mtk_devapc_vio_dbgs_desc *vio_dbgs_desc; + u32 *pds_offset; +}; + +#endif /* __MTK_DEVAPC_H__ */ -- 1.7.9.5 _______________________________________________ Linux-mediatek mailing list Linux-mediatek@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-mediatek 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.7 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,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 B9C3EC433DF for ; Thu, 9 Jul 2020 09:14:16 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7E98E206E2 for ; Thu, 9 Jul 2020 09:14:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="ifhJmsu9"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="Cb85n6SR" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7E98E206E2 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-ID:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=IUUrIx0kBzxuQ/z+9PQKP3BKbDbXB80nmddTidUdoLE=; b=ifhJmsu9GZJZX5cfwkeGJ8pOG 5ocTDUpR1KRrXAdPMEfSt5gm1uaKLpQqlVai8Ix2/UF7eeNwRitF1GQsV2esF1tvvcFazoIj4X0W+ y8lgYvesJc6tSy8sj305bSccnbUUkI1IZPLwq1PDPeTynrKGIEI3u6QYwxINWVF/fD7Ld5I15gmWB M3vrYnEyv5Y8xarFKJG+K9N8QY/ngVY9Y+JTNYhf9QZgmIAFC50AmNUOMDZ4uiubXqdpLB3kwa0V8 v1HLITO7OBwI7RSFO786ZLkLXteEM5lt119RTnUWXMkM/p1qYyay/41OsLBaYLrEE1H5FQPrAvAo4 Z5wl+bUEQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jtSbm-0002cD-Pq; Thu, 09 Jul 2020 09:12:46 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jtSbT-0002RM-LH; Thu, 09 Jul 2020 09:12:30 +0000 X-UUID: e8910e14e9ca498bb235633d41520a91-20200709 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=uEIodGb+H0SrBqh8VNgfTXkSpyd8DbLFMTrEpDE4eVA=; b=Cb85n6SRfM7l5AP9Kod9cb4gFsFaQaQQk+7QKqmUkVd/txieafbi6bgT+wLNSWO05k4UB5YXGGRaY0eczPcvdYH3C09Te/DQodM2Nx2oq6AQxkPBexoMPyVjCD+yjyMyuuO/N6I9LCuprPNh1xTL+LUwIN1srLq0z0da6+hPy3c=; X-UUID: e8910e14e9ca498bb235633d41520a91-20200709 Received: from mtkcas68.mediatek.inc [(172.29.94.19)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLS) with ESMTP id 344245934; Thu, 09 Jul 2020 01:12:10 -0800 Received: from MTKMBS01N1.mediatek.inc (172.21.101.68) by MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 9 Jul 2020 02:12:17 -0700 Received: from mtkcas08.mediatek.inc (172.21.101.126) by mtkmbs01n1.mediatek.inc (172.21.101.68) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 9 Jul 2020 17:12:16 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas08.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 9 Jul 2020 17:12:18 +0800 From: Neal Liu To: Rob Herring , Matthias Brugger Subject: [PATCH v2 2/2] soc: mediatek: add mtk-devapc driver Date: Thu, 9 Jul 2020 17:12:07 +0800 Message-ID: <1594285927-1840-3-git-send-email-neal.liu@mediatek.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1594285927-1840-1-git-send-email-neal.liu@mediatek.com> References: <1594285927-1840-1-git-send-email-neal.liu@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200709_051228_088480_044CABEF X-CRM114-Status: GOOD ( 24.12 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, wsd_upstream@mediatek.com, lkml , linux-mediatek@lists.infradead.org, Neal Liu , linux-arm-kernel@lists.infradead.org Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org MediaTek bus fabric provides TrustZone security support and data protection to prevent slaves from being accessed by unexpected masters. The security violation is logged and sent to the processor for further analysis or countermeasures. Any occurrence of security violation would raise an interrupt, and it will be handled by mtk-devapc driver. The violation information is printed in order to find the murderer. Signed-off-by: Neal Liu --- drivers/soc/mediatek/Kconfig | 9 + drivers/soc/mediatek/Makefile | 1 + drivers/soc/mediatek/mtk-devapc.c | 466 ++++++++++++++++++++++++++ drivers/soc/mediatek/mtk-devapc.h | 670 +++++++++++++++++++++++++++++++++++++ 4 files changed, 1146 insertions(+) create mode 100644 drivers/soc/mediatek/mtk-devapc.c create mode 100644 drivers/soc/mediatek/mtk-devapc.h diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig index 59a56cd..1177c98 100644 --- a/drivers/soc/mediatek/Kconfig +++ b/drivers/soc/mediatek/Kconfig @@ -17,6 +17,15 @@ config MTK_CMDQ time limitation, such as updating display configuration during the vblank. +config MTK_DEVAPC + tristate "Mediatek Device APC Support" + help + Say yes here to enable support for Mediatek Device APC driver. + This driver is mainly used to handle the violation which catches + unexpected transaction. + The violation information is logged for further analysis or + countermeasures. + config MTK_INFRACFG bool "MediaTek INFRACFG Support" select REGMAP diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile index 01f9f87..abfd4ba 100644 --- a/drivers/soc/mediatek/Makefile +++ b/drivers/soc/mediatek/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o +obj-$(CONFIG_MTK_DEVAPC) += mtk-devapc.o obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c new file mode 100644 index 0000000..11fa366 --- /dev/null +++ b/drivers/soc/mediatek/mtk-devapc.c @@ -0,0 +1,466 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include "mtk-devapc.h" + +/* + * mtk_devapc_pd_get - get devapc pd_types of register address. + * + * Returns the value of reg addr + */ +static void __iomem *mtk_devapc_pd_get(struct mtk_devapc_context *devapc_ctx, + int slave_type, + enum DEVAPC_PD_REG_TYPE pd_reg_type, + u32 reg_idx) +{ + void __iomem *reg; + + reg = devapc_ctx->devapc_pd_base[slave_type] + + devapc_ctx->pds_offset[pd_reg_type]; + + if (pd_reg_type == VIO_MASK || pd_reg_type == VIO_STA) + reg += 0x4 * reg_idx; + + return reg; +} + +static int get_vio_slave_num(int slave_type) +{ + if (slave_type == 0) + return ARRAY_SIZE(mtk_devices_infra); + + return 0; +} + +static u32 get_shift_group(struct mtk_devapc_context *devapc_ctx, + int slave_type, int vio_idx) +{ + u32 vio_shift_sta; + void __iomem *reg; + int bit; + + reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_SHIFT_STA, 0); + vio_shift_sta = readl(reg); + + for (bit = 0; bit < 32; bit++) { + if ((vio_shift_sta >> bit) & 0x1) + break; + } + + return bit; +} + +static int check_vio_mask_sta(struct mtk_devapc_context *devapc_ctx, + int slave_type, u32 module, int pd_reg_type) +{ + u32 reg_index, reg_offset; + void __iomem *reg; + u32 value; + + VIO_MASK_STA_REG_GET(module); + + reg = mtk_devapc_pd_get(devapc_ctx, slave_type, pd_reg_type, reg_index); + value = readl(reg); + + return ((value >> reg_offset) & 0x1); +} + +static int check_vio_mask(struct mtk_devapc_context *devapc_ctx, int slave_type, + u32 module) +{ + return check_vio_mask_sta(devapc_ctx, slave_type, module, VIO_MASK); +} + +static int check_vio_status(struct mtk_devapc_context *devapc_ctx, + int slave_type, u32 module) +{ + return check_vio_mask_sta(devapc_ctx, slave_type, module, VIO_STA); +} + +static void clear_vio_status(struct mtk_devapc_context *devapc_ctx, + int slave_type, u32 module) +{ + u32 reg_index, reg_offset; + void __iomem *reg; + + VIO_MASK_STA_REG_GET(module); + + reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_STA, reg_index); + writel(0x1 << reg_offset, reg); + + if (check_vio_status(devapc_ctx, slave_type, module)) + pr_err(PFX "%s: Clear failed, slave_type:0x%x, module_index:0x%x\n", + __func__, slave_type, module); +} + +static void mask_module_irq(struct mtk_devapc_context *devapc_ctx, + int slave_type, u32 module, bool mask) +{ + u32 reg_index, reg_offset; + void __iomem *reg; + u32 value; + + VIO_MASK_STA_REG_GET(module); + + reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_MASK, reg_index); + + value = readl(reg); + if (mask) + value |= (0x1 << reg_offset); + else + value &= ~(0x1 << reg_offset); + + writel(value, reg); +} + +#define TIMEOUT_MS 10000 + +static int read_poll_timeout(void __iomem *addr, u32 mask) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS); + + do { + if (readl_relaxed(addr) & mask) + return 0; + + } while (!time_after(jiffies, timeout)); + + return (readl_relaxed(addr) & mask) ? 0 : -ETIMEDOUT; +} + +/* + * sync_vio_dbg - start to get violation information by selecting violation + * group and enable violation shift. + * + * Returns sync done or not + */ +static u32 sync_vio_dbg(struct mtk_devapc_context *devapc_ctx, int slave_type, + u32 shift_bit) +{ + void __iomem *pd_vio_shift_sta_reg; + void __iomem *pd_vio_shift_sel_reg; + void __iomem *pd_vio_shift_con_reg; + u32 sync_done = 0; + + pd_vio_shift_sta_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_STA, 0); + pd_vio_shift_sel_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_SEL, 0); + pd_vio_shift_con_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_CON, 0); + + writel(0x1 << shift_bit, pd_vio_shift_sel_reg); + writel(0x1, pd_vio_shift_con_reg); + + if (!read_poll_timeout(pd_vio_shift_con_reg, 0x2)) + sync_done = 1; + else + pr_err(PFX "%s: Shift violation info failed\n", __func__); + + /* Disable shift mechanism */ + writel(0x0, pd_vio_shift_con_reg); + writel(0x0, pd_vio_shift_sel_reg); + writel(0x1 << shift_bit, pd_vio_shift_sta_reg); + + return sync_done; +} + +static void devapc_vio_info_print(struct mtk_devapc_context *devapc_ctx) +{ + struct mtk_devapc_vio_info *vio_info = devapc_ctx->vio_info; + + /* Print violation information */ + if (vio_info->write) + pr_info(PFX "Write Violation\n"); + else if (vio_info->read) + pr_info(PFX "Read Violation\n"); + + pr_info(PFX "%s%x, %s%x, %s%x, %s%x\n", + "Vio Addr:0x", vio_info->vio_addr, + "High:0x", vio_info->vio_addr_high, + "Bus ID:0x", vio_info->master_id, + "Dom ID:0x", vio_info->domain_id); +} + +static void devapc_extract_vio_dbg(struct mtk_devapc_context *devapc_ctx, + int slave_type) +{ + void __iomem *vio_dbg0_reg, *vio_dbg1_reg; + struct mtk_devapc_vio_dbgs_desc *vio_dbgs; + struct mtk_devapc_vio_info *vio_info; + u32 dbg0; + + vio_dbg0_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_DBG0, 0); + vio_dbg1_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, VIO_DBG1, 0); + + vio_dbgs = devapc_ctx->vio_dbgs_desc; + vio_info = devapc_ctx->vio_info; + + /* Extract violation information */ + dbg0 = readl(vio_dbg0_reg); + vio_info->vio_addr = readl(vio_dbg1_reg); + + vio_info->master_id = (dbg0 & vio_dbgs[MSTID].mask) >> + vio_dbgs[MSTID].start_bit; + vio_info->domain_id = (dbg0 & vio_dbgs[DMNID].mask) >> + vio_dbgs[DMNID].start_bit; + vio_info->write = ((dbg0 & vio_dbgs[VIO_W].mask) >> + vio_dbgs[VIO_W].start_bit) == 1; + vio_info->read = ((dbg0 & vio_dbgs[VIO_R].mask) >> + vio_dbgs[VIO_R].start_bit) == 1; + vio_info->vio_addr_high = (dbg0 & vio_dbgs[ADDR_H].mask) >> + vio_dbgs[ADDR_H].start_bit; + + devapc_vio_info_print(devapc_ctx); +} + +/* + * mtk_devapc_dump_vio_dbg - shift & dump the violation debug information. + */ +static bool mtk_devapc_dump_vio_dbg(struct mtk_devapc_context *devapc_ctx, + int slave_type, int *vio_idx) +{ + const struct mtk_device_info **device_info; + u32 shift_bit; + int i; + + device_info = devapc_ctx->device_info; + + for (i = 0; i < get_vio_slave_num(slave_type); i++) { + *vio_idx = device_info[slave_type][i].vio_index; + + if (check_vio_mask(devapc_ctx, slave_type, *vio_idx)) + continue; + + if (!check_vio_status(devapc_ctx, slave_type, *vio_idx)) + continue; + + shift_bit = get_shift_group(devapc_ctx, slave_type, *vio_idx); + + if (!sync_vio_dbg(devapc_ctx, slave_type, shift_bit)) + continue; + + devapc_extract_vio_dbg(devapc_ctx, slave_type); + + return true; + } + + return false; +} + +/* + * devapc_violation_irq - the devapc Interrupt Service Routine (ISR) will dump + * violation information including which master violates + * access slave. + */ +static irqreturn_t devapc_violation_irq(int irq_number, + struct mtk_devapc_context *devapc_ctx) +{ + const struct mtk_device_info **device_info; + int slave_type_num; + int vio_idx = -1; + int slave_type; + + slave_type_num = devapc_ctx->slave_type_num; + device_info = devapc_ctx->device_info; + + for (slave_type = 0; slave_type < slave_type_num; slave_type++) { + if (!mtk_devapc_dump_vio_dbg(devapc_ctx, slave_type, &vio_idx)) + continue; + + /* Ensure that violation info are written before + * further operations + */ + smp_mb(); + + mask_module_irq(devapc_ctx, slave_type, vio_idx, true); + + clear_vio_status(devapc_ctx, slave_type, vio_idx); + + mask_module_irq(devapc_ctx, slave_type, vio_idx, false); + } + + return IRQ_HANDLED; +} + +/* + * start_devapc - initialize devapc status and start receiving interrupt + * while devapc violation is triggered. + */ +static void start_devapc(struct mtk_devapc_context *devapc_ctx) +{ + const struct mtk_device_info **device_info; + void __iomem *pd_vio_shift_sta_reg; + void __iomem *pd_apc_con_reg; + u32 vio_shift_sta; + int slave_type, slave_type_num; + int i, vio_idx; + + device_info = devapc_ctx->device_info; + slave_type_num = devapc_ctx->slave_type_num; + + for (slave_type = 0; slave_type < slave_type_num; slave_type++) { + pd_apc_con_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + APC_CON, 0); + pd_vio_shift_sta_reg = mtk_devapc_pd_get(devapc_ctx, slave_type, + VIO_SHIFT_STA, 0); + if (!pd_apc_con_reg || !pd_vio_shift_sta_reg) + return; + + /* Clear devapc violation status */ + writel(BIT(31), pd_apc_con_reg); + + /* Clear violation shift status */ + vio_shift_sta = readl(pd_vio_shift_sta_reg); + if (vio_shift_sta) + writel(vio_shift_sta, pd_vio_shift_sta_reg); + + /* Clear slave violation status */ + for (i = 0; i < get_vio_slave_num(slave_type); i++) { + vio_idx = device_info[slave_type][i].vio_index; + + clear_vio_status(devapc_ctx, slave_type, vio_idx); + + mask_module_irq(devapc_ctx, slave_type, vio_idx, false); + } + } +} + +static int mtk_devapc_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct mtk_devapc_context *devapc_ctx; + struct clk *devapc_infra_clk; + u32 vio_dbgs_num, pds_num; + u8 slave_type_num; + u32 devapc_irq; + size_t size; + int i, ret; + + if (IS_ERR(node)) + return -ENODEV; + + devapc_ctx = devm_kzalloc(&pdev->dev, sizeof(struct mtk_devapc_context), + GFP_KERNEL); + if (!devapc_ctx) + return -ENOMEM; + + if (of_property_read_u8(node, "mediatek-slv_type_num", &slave_type_num)) + return -ENXIO; + + devapc_ctx->slave_type_num = slave_type_num; + + size = slave_type_num * sizeof(void *); + devapc_ctx->devapc_pd_base = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!devapc_ctx->devapc_pd_base) + return -ENOMEM; + + size = slave_type_num * sizeof(struct mtk_device_info *); + devapc_ctx->device_info = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!devapc_ctx->device_info) + return -ENOMEM; + + for (i = 0; i < slave_type_num; i++) { + devapc_ctx->devapc_pd_base[i] = of_iomap(node, i); + if (!devapc_ctx->devapc_pd_base[i]) + return -EINVAL; + + if (i == 0) + devapc_ctx->device_info[i] = mtk_devices_infra; + } + + size = sizeof(struct mtk_devapc_vio_info); + devapc_ctx->vio_info = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!devapc_ctx->vio_info) + return -ENOMEM; + + vio_dbgs_num = of_property_count_u32_elems(node, "mediatek-vio_dbgs"); + if (vio_dbgs_num <= 0) + return -ENXIO; + + size = (vio_dbgs_num / 2) * sizeof(struct mtk_devapc_vio_dbgs_desc); + devapc_ctx->vio_dbgs_desc = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!devapc_ctx->vio_dbgs_desc) + return -ENOMEM; + + for (i = 0; i < vio_dbgs_num / 2; i++) { + if (of_property_read_u32_index(node, "mediatek-vio_dbgs", + i * 2, + &devapc_ctx->vio_dbgs_desc[i].mask)) + return -ENXIO; + + if (of_property_read_u32_index(node, "mediatek-vio_dbgs", + (i * 2) + 1, + &devapc_ctx->vio_dbgs_desc[i].start_bit)) + return -ENXIO; + } + + pds_num = of_property_count_u32_elems(node, "mediatek-pds_offset"); + if (pds_num <= 0) + return -ENXIO; + + size = pds_num * sizeof(u32); + devapc_ctx->pds_offset = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!devapc_ctx->pds_offset) + return -ENOMEM; + + for (i = 0; i < pds_num; i++) { + if (of_property_read_u32_index(node, "mediatek-pds_offset", i, + &devapc_ctx->pds_offset[i])) + return -ENXIO; + } + + devapc_irq = irq_of_parse_and_map(node, 0); + if (!devapc_irq) + return -EINVAL; + + devapc_infra_clk = devm_clk_get(&pdev->dev, "devapc-infra-clock"); + if (IS_ERR(devapc_infra_clk)) + return -EINVAL; + + if (clk_prepare_enable(devapc_infra_clk)) + return -EINVAL; + + start_devapc(devapc_ctx); + + ret = devm_request_irq(&pdev->dev, devapc_irq, + (irq_handler_t)devapc_violation_irq, + IRQF_TRIGGER_NONE, "devapc", devapc_ctx); + if (ret) + return ret; + + return 0; +} + +static int mtk_devapc_remove(struct platform_device *dev) +{ + return 0; +} + +static const struct of_device_id mtk_devapc_dt_match[] = { + { .compatible = "mediatek,mt6779-devapc" }, + {}, +}; + +static struct platform_driver mtk_devapc_driver = { + .probe = mtk_devapc_probe, + .remove = mtk_devapc_remove, + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = mtk_devapc_dt_match, + }, +}; + +module_platform_driver(mtk_devapc_driver); + +MODULE_DESCRIPTION("Mediatek Device APC Driver"); +MODULE_AUTHOR("Neal Liu "); +MODULE_LICENSE("GPL"); diff --git a/drivers/soc/mediatek/mtk-devapc.h b/drivers/soc/mediatek/mtk-devapc.h new file mode 100644 index 0000000..ab2cb14 --- /dev/null +++ b/drivers/soc/mediatek/mtk-devapc.h @@ -0,0 +1,670 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 MediaTek Inc. + */ + +#ifndef __MTK_DEVAPC_H__ +#define __MTK_DEVAPC_H__ + +#define PFX "[DEVAPC]: " + +#define VIO_MASK_STA_REG_GET(m) \ +({ \ + typeof(m) (_m) = (m); \ + reg_index = _m / 32; \ + reg_offset = _m % 32; \ +}) + +enum DEVAPC_PD_REG_TYPE { + VIO_MASK = 0, + VIO_STA, + VIO_DBG0, + VIO_DBG1, + APC_CON, + VIO_SHIFT_STA, + VIO_SHIFT_SEL, + VIO_SHIFT_CON, + PD_REG_TYPE_NUM, +}; + +enum DEVAPC_VIO_DBGS_TYPE { + MSTID = 0, + DMNID, + VIO_W, + VIO_R, + ADDR_H, +}; + +struct mtk_device_info { + int sys_index; + int ctrl_index; + int vio_index; +}; + +static struct mtk_device_info mtk_devices_infra[] = { + /* sys_idx, ctrl_idx, vio_idx */ + /* 0 */ + {0, 0, 0}, + {0, 1, 1}, + {0, 2, 2}, + {0, 3, 3}, + {0, 4, 4}, + {0, 5, 5}, + {0, 6, 6}, + {0, 7, 7}, + {0, 8, 8}, + {0, 9, 9}, + + /* 10 */ + {0, 10, 10}, + {0, 11, 11}, + {0, 12, 12}, + {0, 13, 13}, + {0, 14, 14}, + {0, 15, 15}, + {0, 16, 16}, + {0, 17, 17}, + {0, 18, 18}, + {0, 19, 19}, + + /* 20 */ + {0, 20, 20}, + {0, 21, 21}, + {0, 22, 22}, + {0, 23, 23}, + {0, 24, 24}, + {0, 25, 25}, + {0, 26, 26}, + {0, 27, 27}, + {0, 28, 28}, + {0, 29, 29}, + + /* 30 */ + {0, 30, 30}, + {0, 31, 31}, + {0, 32, 32}, + {0, 33, 77}, + {0, 34, 78}, + {0, 35, 79}, + {0, 35, 80}, + {0, 37, 37}, + {0, 38, 38}, + {0, 39, 39}, + + /* 40 */ + {0, 40, 40}, + {0, 41, 41}, + {0, 42, 42}, + {0, 43, 43}, + {0, 44, 44}, + {0, 45, 45}, + {0, 46, 46}, + {0, 47, 47}, + {0, 48, 48}, + {0, 49, 49}, + + /* 50 */ + {0, 50, 50}, + {0, 51, 51}, + {0, 52, 52}, + {0, 53, 53}, + {0, 54, 54}, + {0, 55, 55}, + {0, 56, 56}, + {0, 57, 57}, + {0, 58, 58}, + {0, 59, 59}, + + /* 60 */ + {0, 60, 60}, + {0, 61, 61}, + {0, 62, 62}, + {0, 63, 63}, + {0, 64, 64}, + {0, 65, 70}, + {0, 66, 71}, + {0, 67, 72}, + {0, 68, 73}, + {0, 70, 81}, + + /* 70 */ + {0, 71, 82}, + {0, 72, 83}, + {0, 73, 84}, + {0, 74, 85}, + {0, 75, 86}, + {0, 76, 87}, + {0, 77, 88}, + {0, 78, 89}, + {0, 79, 90}, + {0, 80, 91}, + + /* 80 */ + {0, 81, 92}, + {0, 82, 93}, + {0, 83, 94}, + {0, 84, 95}, + {0, 85, 96}, + {0, 86, 97}, + {0, 87, 98}, + {0, 88, 99}, + {0, 89, 100}, + {0, 90, 101}, + + /* 90 */ + {0, 91, 102}, + {0, 92, 103}, + {0, 93, 104}, + {0, 94, 105}, + {0, 95, 106}, + {0, 96, 107}, + {0, 97, 108}, + {0, 98, 109}, + {0, 110, 110}, + {0, 111, 111}, + + /* 100 */ + {0, 112, 112}, + {0, 113, 113}, + {0, 114, 114}, + {0, 115, 115}, + {0, 116, 116}, + {0, 117, 117}, + {0, 118, 118}, + {0, 119, 119}, + {0, 120, 120}, + {0, 121, 121}, + + /* 110 */ + {0, 122, 122}, + {0, 123, 123}, + {0, 124, 124}, + {0, 125, 125}, + {0, 126, 126}, + {0, 127, 127}, + {0, 128, 128}, + {0, 129, 129}, + {0, 130, 130}, + {0, 131, 131}, + + /* 120 */ + {0, 132, 132}, + {0, 133, 133}, + {0, 134, 134}, + {0, 135, 135}, + {0, 136, 136}, + {0, 137, 137}, + {0, 138, 138}, + {0, 139, 139}, + {0, 140, 140}, + {0, 141, 141}, + + /* 130 */ + {0, 142, 142}, + {0, 143, 143}, + {0, 144, 144}, + {0, 145, 145}, + {0, 146, 146}, + {0, 147, 147}, + {0, 148, 148}, + {0, 149, 149}, + {0, 150, 150}, + {0, 151, 151}, + + /* 140 */ + {0, 152, 152}, + {0, 153, 153}, + {0, 154, 154}, + {0, 155, 155}, + {0, 156, 156}, + {0, 157, 157}, + {0, 158, 158}, + {0, 159, 159}, + {0, 160, 160}, + {0, 161, 161}, + + /* 150 */ + {0, 162, 162}, + {0, 163, 163}, + {0, 164, 164}, + {0, 165, 165}, + {0, 166, 166}, + {0, 167, 167}, + {0, 168, 168}, + {0, 169, 169}, + {0, 170, 170}, + {0, 171, 171}, + + /* 160 */ + {0, 172, 172}, + {0, 173, 173}, + {0, 174, 174}, + {0, 175, 175}, + {0, 176, 176}, + {0, 177, 177}, + {0, 178, 178}, + {0, 179, 179}, + {0, 180, 180}, + {0, 181, 181}, + + /* 170 */ + {0, 182, 182}, + {0, 183, 183}, + {0, 184, 184}, + {0, 185, 185}, + {0, 186, 186}, + {0, 187, 187}, + {0, 188, 188}, + {0, 189, 189}, + {0, 190, 190}, + {0, 191, 191}, + + /* 180 */ + {0, 192, 192}, + {0, 193, 193}, + {0, 194, 194}, + {0, 195, 195}, + {0, 196, 196}, + {0, 197, 197}, + {0, 198, 198}, + {0, 199, 199}, + {0, 200, 200}, + {0, 201, 201}, + + /* 190 */ + {0, 202, 202}, + {0, 203, 203}, + {0, 204, 204}, + {0, 205, 205}, + {0, 206, 206}, + {0, 207, 207}, + {0, 208, 208}, + {0, 209, 209}, + {0, 210, 210}, + {0, 211, 211}, + + /* 200 */ + {0, 212, 212}, + {0, 213, 213}, + {0, 214, 214}, + {0, 215, 215}, + {0, 216, 216}, + {0, 217, 217}, + {0, 218, 218}, + {0, 219, 219}, + {0, 220, 220}, + {0, 221, 221}, + + /* 210 */ + {0, 222, 222}, + {0, 223, 223}, + {0, 224, 224}, + {0, 225, 225}, + {0, 226, 226}, + {0, 227, 227}, + {0, 228, 228}, + {0, 229, 229}, + {0, 230, 230}, + {0, 231, 231}, + + /* 220 */ + {1, 0, 232}, + {1, 1, 233}, + {1, 2, 234}, + {1, 3, 235}, + {1, 4, 236}, + {1, 5, 237}, + {1, 6, 238}, + {1, 7, 239}, + {1, 8, 240}, + {1, 9, 241}, + + /* 230 */ + {1, 10, 242}, + {1, 11, 243}, + {1, 12, 244}, + {1, 13, 245}, + {1, 14, 246}, + {1, 15, 247}, + {1, 16, 248}, + {1, 17, 249}, + {1, 18, 250}, + {1, 19, 251}, + + /* 240 */ + {1, 20, 252}, + {1, 21, 253}, + {1, 22, 254}, + {1, 23, 255}, + {1, 24, 256}, + {1, 25, 257}, + {1, 26, 258}, + {1, 27, 259}, + {1, 28, 260}, + {1, 29, 261}, + + /* 250 */ + {1, 30, 262}, + {1, 31, 263}, + {1, 32, 264}, + {1, 33, 265}, + {1, 34, 266}, + {1, 35, 267}, + {1, 36, 268}, + {1, 37, 269}, + {1, 38, 270}, + {1, 39, 271}, + + /* 260 */ + {1, 40, 272}, + {1, 41, 273}, + {1, 42, 274}, + {1, 43, 275}, + {1, 44, 276}, + {1, 45, 277}, + {1, 46, 278}, + {1, 47, 279}, + {1, 48, 280}, + {1, 49, 281}, + + /* 270 */ + {1, 50, 282}, + {1, 51, 283}, + {1, 52, 284}, + {1, 53, 285}, + {1, 54, 286}, + {1, 55, 287}, + {1, 56, 288}, + {1, 57, 289}, + {1, 58, 290}, + {1, 59, 291}, + + /* 280 */ + {1, 60, 292}, + {1, 61, 293}, + {1, 62, 294}, + {1, 63, 295}, + {1, 64, 296}, + {1, 65, 297}, + {1, 66, 298}, + {1, 67, 299}, + {1, 68, 300}, + {1, 69, 301}, + + /* 290 */ + {1, 70, 302}, + {1, 71, 303}, + {1, 72, 304}, + {1, 73, 305}, + {1, 74, 306}, + {1, 75, 307}, + {1, 76, 308}, + {1, 77, 309}, + {1, 78, 310}, + {1, 79, 311}, + + /* 300 */ + {1, 80, 312}, + {1, 81, 313}, + {1, 82, 314}, + {1, 83, 315}, + {1, 84, 316}, + {1, 85, 317}, + {1, 86, 318}, + {1, 87, 319}, + {1, 88, 320}, + {1, 89, 321}, + + /* 310 */ + {1, 90, 322}, + {1, 91, 323}, + {1, 92, 324}, + {1, 93, 325}, + {1, 94, 326}, + {1, 95, 327}, + {1, 96, 328}, + {1, 97, 329}, + {1, 98, 330}, + {1, 99, 331}, + + /* 320 */ + {1, 100, 332}, + {1, 101, 333}, + {1, 102, 334}, + {1, 103, 335}, + {1, 104, 336}, + {1, 105, 337}, + {1, 106, 338}, + {1, 107, 339}, + {1, 108, 340}, + {1, 109, 341}, + + /* 330 */ + {1, 110, 342}, + {1, 111, 343}, + {1, 112, 344}, + {1, 113, 345}, + {1, 114, 346}, + {1, 115, 347}, + {1, 116, 348}, + {1, 117, 349}, + {1, 118, 350}, + {1, 119, 351}, + + /* 340 */ + {1, 120, 352}, + {1, 121, 353}, + {1, 122, 354}, + {1, 123, 355}, + {1, 124, 356}, + {1, 125, 357}, + {1, 126, 358}, + {1, 127, 359}, + {1, 128, 360}, + {1, 129, 361}, + + /* 350 */ + {1, 130, 362}, + {1, 131, 363}, + {1, 132, 364}, + {1, 133, 365}, + {1, 134, 366}, + {1, 135, 367}, + {1, 136, 368}, + {1, 137, 369}, + {1, 138, 370}, + {1, 139, 371}, + + /* 360 */ + {1, 140, 372}, + {1, 141, 373}, + {1, 142, 374}, + {1, 143, 375}, + {1, 144, 376}, + {1, 145, 377}, + {1, 146, 378}, + {1, 147, 379}, + {1, 148, 380}, + {1, 149, 381}, + + /* 370 */ + {1, 150, 382}, + {1, 151, 383}, + {1, 152, 384}, + {1, 153, 385}, + {1, 154, 386}, + {1, 155, 387}, + {1, 156, 388}, + {1, 157, 389}, + {1, 158, 390}, + {1, 159, 391}, + + /* 380 */ + {1, 160, 392}, + {1, 161, 393}, + {1, 162, 394}, + {1, 163, 395}, + {1, 164, 396}, + {1, 165, 397}, + {1, 166, 398}, + {1, 167, 399}, + {1, 168, 400}, + {1, 169, 401}, + + /* 390 */ + {1, 170, 402}, + {1, 171, 403}, + {1, 172, 404}, + {1, 173, 405}, + {1, 174, 406}, + {1, 175, 407}, + {1, 176, 408}, + {1, 177, 409}, + {1, 178, 410}, + {1, 179, 411}, + + /* 400 */ + {1, 180, 412}, + {1, 181, 413}, + {1, 182, 414}, + {1, 183, 415}, + {1, 184, 416}, + {1, 185, 417}, + {1, 186, 418}, + {1, 187, 419}, + {1, 188, 420}, + {1, 189, 421}, + + /* 410 */ + {1, 190, 422}, + {1, 191, 423}, + {1, 192, 424}, + {1, 193, 425}, + {1, 194, 426}, + {1, 195, 427}, + {1, 196, 428}, + {1, 197, 429}, + {1, 198, 430}, + {1, 199, 431}, + + /* 420 */ + {1, 200, 432}, + {1, 201, 433}, + {1, 202, 434}, + {1, 203, 435}, + {1, 204, 436}, + {1, 205, 437}, + {1, 206, 438}, + {1, 207, 439}, + {1, 208, 440}, + {1, 209, 441}, + + /* 430 */ + {1, 210, 442}, + {1, 211, 443}, + {1, 212, 444}, + {1, 213, 445}, + {1, 214, 446}, + {1, 215, 447}, + {1, 216, 448}, + {1, 217, 449}, + {1, 218, 450}, + {1, 219, 451}, + + /* 440 */ + {1, 220, 452}, + {1, 221, 453}, + {1, 222, 454}, + {1, 223, 455}, + {1, 224, 456}, + {1, 225, 457}, + {1, 226, 458}, + {1, 227, 459}, + {1, 228, 460}, + {1, 229, 461}, + + /* 450 */ + {1, 230, 462}, + {1, 231, 463}, + {1, 232, 464}, + {1, 233, 465}, + {1, 234, 466}, + {1, 235, 467}, + {1, 236, 468}, + {1, 237, 469}, + {1, 238, 470}, + {1, 239, 471}, + + /* 460 */ + {1, 240, 472}, + {1, 241, 473}, + {1, 242, 474}, + {1, 243, 475}, + {1, 244, 476}, + {1, 245, 477}, + {1, 246, 478}, + {-1, -1, 479}, + {-1, -1, 480}, + {-1, -1, 481}, + + /* 470 */ + {-1, -1, 482}, + {-1, -1, 483}, + {-1, -1, 484}, + {-1, -1, 485}, + {-1, -1, 486}, + {-1, -1, 487}, + {-1, -1, 488}, + {-1, -1, 489}, + {-1, -1, 490}, + {-1, -1, 491}, + + /* 480 */ + {-1, -1, 492}, + {-1, -1, 493}, + {-1, -1, 494}, + {-1, -1, 495}, + {-1, -1, 496}, + {-1, -1, 497}, + {-1, -1, 498}, + {-1, -1, 499}, + {-1, -1, 500}, + {-1, -1, 501}, + + /* 490 */ + {-1, -1, 502}, + {-1, -1, 503}, + {-1, -1, 504}, + {-1, -1, 505}, + {-1, -1, 506}, + {-1, -1, 507}, + {-1, -1, 508}, + {-1, -1, 509}, + {-1, -1, 510}, + +}; + +struct mtk_devapc_vio_info { + bool read; + bool write; + u32 vio_addr; + u32 vio_addr_high; + u32 master_id; + u32 domain_id; +}; + +struct mtk_devapc_vio_dbgs_desc { + u32 mask; + u32 start_bit; +}; + +struct mtk_devapc_context { + u8 slave_type_num; + void __iomem **devapc_pd_base; + const struct mtk_device_info **device_info; + struct mtk_devapc_vio_info *vio_info; + struct mtk_devapc_vio_dbgs_desc *vio_dbgs_desc; + u32 *pds_offset; +}; + +#endif /* __MTK_DEVAPC_H__ */ -- 1.7.9.5 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel