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=-0.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_PASS,T_DKIMWL_WL_MED, URIBL_BLOCKED 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 0ABB4C6778A for ; Mon, 2 Jul 2018 11:51:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9CC1B25162 for ; Mon, 2 Jul 2018 11:51:29 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=onelaird.onmicrosoft.com header.i=@onelaird.onmicrosoft.com header.b="f8kQqS6i" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9CC1B25162 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=lairdtech.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753964AbeGBLv1 (ORCPT ); Mon, 2 Jul 2018 07:51:27 -0400 Received: from mail-bn3nam01on0117.outbound.protection.outlook.com ([104.47.33.117]:65224 "EHLO NAM01-BN3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753032AbeGBLvY (ORCPT ); Mon, 2 Jul 2018 07:51:24 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=onelaird.onmicrosoft.com; s=selector1-lairdtech-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=qRngPaVHgqjGZOYajT5eByqnFVqRvDXpSEKDIFsKOhg=; b=f8kQqS6iOoqvixvXmIuR6ZQj9f2HxUyuyCYe26+5E6rb5yZbD/GKUWk3c4HQhnCAxjTRU1EPAEopZ4fGJDYwzaO3dOEvkg5QRICXCyxvRRmF+xJYM2r3oqEOywVCX6Ak2+feFPxRoHmuqj2Wt07DVo9u+e73a8EkRk6qACVjX3Y= Received: from BY1PR02MB1114.namprd02.prod.outlook.com (10.162.108.140) by BY1PR02MB1099.namprd02.prod.outlook.com (10.162.108.13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.906.26; Mon, 2 Jul 2018 11:51:19 +0000 Received: from BY1PR02MB1114.namprd02.prod.outlook.com ([fe80::d5c4:ef81:b513:f5da]) by BY1PR02MB1114.namprd02.prod.outlook.com ([fe80::d5c4:ef81:b513:f5da%4]) with mapi id 15.20.0906.026; Mon, 2 Jul 2018 11:51:19 +0000 From: Ben Whitten To: =?utf-8?B?QW5kcmVhcyBGw6RyYmVy?= , "netdev@vger.kernel.org" CC: "linux-arm-kernel@lists.infradead.org" , "linux-kernel@vger.kernel.org" , Jian-Hong Pan , Jiri Pirko , Marcel Holtmann , "David S . Miller" , Matthias Brugger , Janus Piwek , =?utf-8?B?TWljaGFlbCBSw7ZkZXI=?= , Dollar Chen , Ken Yu , Steve deRosier , Mark Brown , "linux-spi@vger.kernel.org" Subject: RE: [RFC net-next 15/15] net: lora: Add Semtech SX1301 Thread-Topic: [RFC net-next 15/15] net: lora: Add Semtech SX1301 Thread-Index: AQHUESvvwSr5pLbXbkmh3lgaa2XdVqR70Ggg Date: Mon, 2 Jul 2018 11:51:19 +0000 Message-ID: References: <20180701110804.32415-1-afaerber@suse.de> <20180701110804.32415-16-afaerber@suse.de> In-Reply-To: <20180701110804.32415-16-afaerber@suse.de> Accept-Language: en-GB, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: spf=none (sender IP is ) smtp.mailfrom=Ben.Whitten@lairdtech.com; x-originating-ip: [146.200.117.72] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1;BY1PR02MB1099;7:FoEbTZkaDt89y0vh+vlh1PJ1c8T2KggkltXGCISHCMlsADRyF49NNVuYqBi1H6V3JfrZg91cdim1n9cln0P0q8UjkuAMRQw5N7epquQWvBEXEDOpEJzQ+hvXd1qHkCtyd1e4fZV1JaiJkJPGcbdsmX6pL4lAwsHEKzAgPJzucyyjqQu9aWqxBJIEKIz+pCEaTRmA5DA0BsnaNrBXDFnlubmo7XElOPSYAAWDYxiQslrT4vdY7ku89x/6e0rJVJNM x-ms-exchange-antispam-srfa-diagnostics: SOS; x-ms-office365-filtering-correlation-id: 4cfd64a2-91d1-4811-b3a2-08d5e0122029 x-microsoft-antispam: UriScan:;BCL:0;PCL:0;RULEID:(7020095)(4652040)(8989117)(5600053)(711020)(4534165)(7168020)(4627221)(201703031133081)(201702281549075)(8990107)(2017052603328)(7153060)(7193020);SRVR:BY1PR02MB1099; x-ms-traffictypediagnostic: BY1PR02MB1099: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(166708455590820)(9452136761055)(85827821059158); x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0;PCL:0;RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(93006095)(93001095)(3002001)(3231254)(944501410)(52105095)(10201501046)(149027)(150027)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123560045)(20161123558120)(20161123562045)(20161123564045)(6072148)(201708071742011)(7699016);SRVR:BY1PR02MB1099;BCL:0;PCL:0;RULEID:;SRVR:BY1PR02MB1099; x-forefront-prvs: 07215D0470 x-forefront-antispam-report: SFV:NSPM;SFS:(10019020)(136003)(39860400002)(366004)(346002)(376002)(396003)(199004)(189003)(4326008)(81156014)(25786009)(81166006)(55236004)(476003)(966005)(2906002)(8676002)(110136005)(316002)(72206003)(55016002)(5660300001)(478600001)(446003)(486006)(11346002)(39060400002)(8936002)(6306002)(54906003)(5250100002)(9686003)(7696005)(102836004)(6506007)(76176011)(229853002)(53936002)(3846002)(6116002)(86362001)(26005)(99286004)(256004)(2900100001)(186003)(97736004)(68736007)(6436002)(6246003)(14454004)(2501003)(106356001)(66066001)(305945005)(33656002)(74316002)(7736002)(105586002)(7416002);DIR:OUT;SFP:1102;SCL:1;SRVR:BY1PR02MB1099;H:BY1PR02MB1114.namprd02.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;A:1;MX:1; received-spf: None (protection.outlook.com: lairdtech.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: Wct0hMLQxC+owi8Wlo1scmeGKslL9N/R+YishcgIJatZ4XlGDyvprLArAzr6LreED2nelOfQ/98pJjaCejUPmTbnrXDVubaK923jG/iyE2yX+k/7nTTm60FCqt6113eFq8MTuIRiT2isQB0lIQamTbL7e+avCX8px/Unl/y7hvfWXB8XlwyUnQY7GBlA5z1403QjCii+AmColnf9qWnNro+0pIK7gMPdJ9kGtB65HUlq/YB5VHNlr9Me6MfnVRb1rc5QqXWM1tuJqIRqacQW27T3y4gV0D46XypOnVXstvvc0S0ZcOvRjNopld7rtuUZCxKEdAQqK7vw3DphdmKtebAxUpvLZk8TUYUTtnNZfrw= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 MIME-Version: 1.0 X-OriginatorOrg: lairdtech.com X-MS-Exchange-CrossTenant-Network-Message-Id: 4cfd64a2-91d1-4811-b3a2-08d5e0122029 X-MS-Exchange-CrossTenant-originalarrivaltime: 02 Jul 2018 11:51:19.4418 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: c4d27a54-2db1-4088-a044-1a83c778ad1b X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY1PR02MB1099 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org SGkgQW5kcmVhcywNCg0KRXhjZWxsZW50IHdvcmsgb24gZG9pbmcgdGhpcyBJIGhhdmUgYWxzbyBi ZWVuIHdvcmtpbmcgb24gYW5kIG9mZg0KdGhpcyBwZXJzb25hbGx5IGZvciBzb21lIHRpbWUuDQpI YXZlIGEgbG9vayBhdCBteSByZXBvc2l0b3J5IFsxXSBmb3Igc3gxMzAxIGFuZCBzeDEyNTcgZHJp dmVycywNCkkgdXNlIHJlZ21hcHMgY2FwYWJpbGl0eSBvZiBzd2l0Y2hpbmcgcGFnZXMgd2hpY2gg c2hvdWxkIHNpbXBsaWZ5DQp5b3VyIGRyaXZlciBjb25zaWRlcmFibHksIEkgYWxzbyBoYXZlIGEg ZnVsbCByZWdpc3RlciBtYXAgYW5kIGJpdCBmaWVsZC4NCg0KSSBoYXZlIGFsc28gYmVlbiB0cnlp bmcgdG8gdXNlIHRoZSBjbGsgZnJhbWV3b3JrIHRvIGNhcHR1cmUgdGhlIHZhcmlvdXMNCnJvdXRp bmcgdGhhdCB0aGUgY2FyZHMgaGF2ZS4NCg0KSSB3aWxsIGRpZyBpbnRvIHRoaXMgc2VyaWVzIHRo aXMgZXZlbmluZy4NCg0KWzFdIGh0dHBzOi8vZ2l0aHViLmNvbS9CV2hpdHRlbi9saW51eC1zdGFi bGUvdHJlZS85NzFhYWRjOGZkZmU4NDIwMjBkOTEyNDQ5YmRkNzFiMzNkNTc2ZmUzL2RyaXZlcnMv bmV0L2xvcmENCg0KDQo+IFN1YmplY3Q6IFtSRkMgbmV0LW5leHQgMTUvMTVdIG5ldDogbG9yYTog QWRkIFNlbXRlY2ggU1gxMzAxDQo+IA0KPiBUaGUgU2VtdGVjaCBTWDEzMDEgd2FzIHRoZSBmaXJz dCBtdWx0aS1jaGFubmVsIExvUmEgImNvbmNlbnRyYXRvciIuDQo+IEl0IHVzZXMgYSBTUEkgaW50 ZXJmYWNlIHRvIHRoZSBob3N0IGFzIHdlbGwgYXMgYSBkdWFsIFNQSSBpbnRlcmZhY2UgdG8NCj4g aXRzIHJhZGlvcy4gVGhlc2UgdHdvIGhhdmUgYmVlbiBpbXBsZW1lbnRlZCBhcyBzcGlfY29udHJv bGxlciwgc28gdGhhdA0KPiB0aGUgRGV2aWNlIFRyZWUgY2FuIHNwZWNpZnkgd2hldGhlciB0aGUg cmVzcGVjdGl2ZSBtb2R1bGUgdXNlcyB0d28NCj4gU1gxMjU3LCB0d28gU1gxMjU1IG9yIGEgY29t YmluYXRpb24gb2YgdGhlc2Ugb3Igc29tZSB1bmZvcmVzZWVuIGNoaXBzZXQuDQo+IA0KPiBUaGlz IGltcGxlbWVudGF0aW9uIGlzIHRoZSBtb3N0IHJlY2VudCAtIGluaXRpYWxpemF0aW9uIGlzIG5v dCB5ZXQNCj4gY29tcGxldGUsIGl0IHdpbGwgbmVlZCB0byBsb2FkIGZpcm13YXJlIGludG8gdGhl IHR3byBvbi1jaGlwIE1DVXMuDQo+IA0KPiBVbmZvcnR1bmF0ZWx5IHRoZXJlIGlzIG5vIGZ1bGwg ZGF0YXNoZWV0IHdpdGggcmVnaXN0ZXIgZGVzY3JpcHRpb25zLA0KPiBvbmx5IGEgQlNELWxpY2Vu c2VkIHVzZXJzcGFjZSBIQUwgaW1wbGVtZW50YXRpb24gdXNpbmcgc3BpZGV2IGRldmljZXMuDQo+ IFRoZXJlZm9yZSBzb21lIHJlZ2lzdGVyIG5hbWVzIGFyZSB1bmtub3duLg0KPiANCj4gQ2M6IEJl biBXaGl0dGVuIDxiZW4ud2hpdHRlbkBsYWlyZHRlY2guY29tPg0KPiBDYzogU3RldmUgZGVSb3Np ZXIgPGRlcm9zaWVyQGdtYWlsLmNvbT4NCj4gQ2M6IE1hcmsgQnJvd24gPGJyb29uaWVAa2VybmVs Lm9yZz4NCj4gQ2M6IE1pY2hhZWwgUsO2ZGVyIDxtaWNoYWVsLnJvZWRlckBhdm5ldC5ldT4NCj4g Q2M6IEtlbiBZdSAo56a55YevKSA8a2VuLnl1QHJha3dpcmVsZXNzLmNvbT4NCj4gQ2M6IGxpbnV4 LXNwaUB2Z2VyLmtlcm5lbC5vcmcNCj4gU2lnbmVkLW9mZi1ieTogQW5kcmVhcyBGw6RyYmVyIDxh ZmFlcmJlckBzdXNlLmRlPg0KPiAtLS0NCj4gIGRyaXZlcnMvbmV0L2xvcmEvS2NvbmZpZyAgfCAg IDcgKw0KPiAgZHJpdmVycy9uZXQvbG9yYS9NYWtlZmlsZSB8ICAgMyArDQo+ICBkcml2ZXJzL25l dC9sb3JhL3N4MTMwMS5jIHwgNDQ2DQo+ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysNCj4gIDMgZmlsZXMgY2hhbmdlZCwgNDU2IGluc2VydGlvbnMoKykNCj4g IGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL25ldC9sb3JhL3N4MTMwMS5jDQo+IA0KPiBkaWZm IC0tZ2l0IGEvZHJpdmVycy9uZXQvbG9yYS9LY29uZmlnIGIvZHJpdmVycy9uZXQvbG9yYS9LY29u ZmlnDQo+IGluZGV4IDY4Yzc0ODBkNzgxMi4uOTUwNDUwZTM1M2I0IDEwMDY0NA0KPiAtLS0gYS9k cml2ZXJzL25ldC9sb3JhL0tjb25maWcNCj4gKysrIGIvZHJpdmVycy9uZXQvbG9yYS9LY29uZmln DQo+IEBAIC00NSw2ICs0NSwxMyBAQCBjb25maWcgTE9SQV9TWDEyNzYNCj4gIAloZWxwDQo+ICAJ ICBTZW10ZWNoIFNYMTI3Mi8xMjc2LzEyNzgNCj4gDQo+ICtjb25maWcgTE9SQV9TWDEzMDENCj4g Kwl0cmlzdGF0ZSAiU2VtdGVjaCBTWDEzMDEgU1BJIGRyaXZlciINCj4gKwlkZWZhdWx0IHkNCj4g KwlkZXBlbmRzIG9uIFNQSQ0KPiArCWhlbHANCj4gKwkgIFNlbXRlY2ggU1gxMzAxDQo+ICsNCj4g IGNvbmZpZyBMT1JBX1VTSQ0KPiAgCXRyaXN0YXRlICJVU0kgV00tU0ctU00tNDIgZHJpdmVyIg0K PiAgCWRlZmF1bHQgeQ0KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9uZXQvbG9yYS9NYWtlZmlsZSBi L2RyaXZlcnMvbmV0L2xvcmEvTWFrZWZpbGUNCj4gaW5kZXggNDRjNTc4YmRlN2Q1Li4xY2MxZTNh YTE4OWIgMTAwNjQ0DQo+IC0tLSBhL2RyaXZlcnMvbmV0L2xvcmEvTWFrZWZpbGUNCj4gKysrIGIv ZHJpdmVycy9uZXQvbG9yYS9NYWtlZmlsZQ0KPiBAQCAtMjIsNiArMjIsOSBAQCBsb3JhLXN4MTI1 Ny15IDo9IHN4MTI1Ny5vDQo+ICBvYmotJChDT05GSUdfTE9SQV9TWDEyNzYpICs9IGxvcmEtc3gx Mjc2Lm8NCj4gIGxvcmEtc3gxMjc2LXkgOj0gc3gxMjc2Lm8NCj4gDQo+ICtvYmotJChDT05GSUdf TE9SQV9TWDEzMDEpICs9IGxvcmEtc3gxMzAxLm8NCj4gK2xvcmEtc3gxMzAxLXkgOj0gc3gxMzAx Lm8NCj4gKw0KPiAgb2JqLSQoQ09ORklHX0xPUkFfVVNJKSArPSBsb3JhLXVzaS5vDQo+ICBsb3Jh LXVzaS15IDo9IHVzaS5vDQo+IA0KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9uZXQvbG9yYS9zeDEz MDEuYyBiL2RyaXZlcnMvbmV0L2xvcmEvc3gxMzAxLmMNCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQN Cj4gaW5kZXggMDAwMDAwMDAwMDAwLi41YzkzNmMxMTE2ZDENCj4gLS0tIC9kZXYvbnVsbA0KPiAr KysgYi9kcml2ZXJzL25ldC9sb3JhL3N4MTMwMS5jDQo+IEBAIC0wLDAgKzEsNDQ2IEBADQo+ICsv LyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMC1vci1sYXRlcg0KPiArLyoNCj4gKyAq IFNlbXRlY2ggU1gxMzAxIExvUmEgY29uY2VudHJhdG9yDQo+ICsgKg0KPiArICogQ29weXJpZ2h0 IChjKSAyMDE4IEFuZHJlYXMgRsOkcmJlcg0KPiArICoNCj4gKyAqIEJhc2VkIG9uIFNYMTMwMSBI QUwgY29kZToNCj4gKyAqIENvcHlyaWdodCAoYykgMjAxMyBTZW10ZWNoLUN5Y2xlbw0KPiArICov DQo+ICsNCj4gKyNpbmNsdWRlIDxsaW51eC9iaXRvcHMuaD4NCj4gKyNpbmNsdWRlIDxsaW51eC9k ZWxheS5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2xvcmEuaD4NCj4gKyNpbmNsdWRlIDxsaW51eC9t b2R1bGUuaD4NCj4gKyNpbmNsdWRlIDxsaW51eC9uZXRkZXZpY2UuaD4NCj4gKyNpbmNsdWRlIDxs aW51eC9vZi5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L29mX2RldmljZS5oPg0KPiArI2luY2x1ZGUg PGxpbnV4L29mX2dwaW8uaD4NCj4gKyNpbmNsdWRlIDxsaW51eC9sb3JhL2Rldi5oPg0KPiArI2lu Y2x1ZGUgPGxpbnV4L3NwaS9zcGkuaD4NCj4gKw0KPiArI2RlZmluZSBSRUdfUEFHRV9SRVNFVAkJ CTANCj4gKyNkZWZpbmUgUkVHX1ZFUlNJT04JCQkxDQo+ICsjZGVmaW5lIFJFR18yX1NQSV9SQURJ T19BX0RBVEEJCTMzDQo+ICsjZGVmaW5lIFJFR18yX1NQSV9SQURJT19BX0RBVEFfUkVBREJBQ0sJ MzQNCj4gKyNkZWZpbmUgUkVHXzJfU1BJX1JBRElPX0FfQUREUgkJMzUNCj4gKyNkZWZpbmUgUkVH XzJfU1BJX1JBRElPX0FfQ1MJCTM3DQo+ICsjZGVmaW5lIFJFR18yX1NQSV9SQURJT19CX0RBVEEJ CTM4DQo+ICsjZGVmaW5lIFJFR18yX1NQSV9SQURJT19CX0RBVEFfUkVBREJBQ0sJMzkNCj4gKyNk ZWZpbmUgUkVHXzJfU1BJX1JBRElPX0JfQUREUgkJNDANCj4gKyNkZWZpbmUgUkVHXzJfU1BJX1JB RElPX0JfQ1MJCTQyDQo+ICsNCj4gKyNkZWZpbmUgUkVHX1BBR0VfUkVTRVRfU09GVF9SRVNFVAlC SVQoNykNCj4gKw0KPiArI2RlZmluZSBSRUdfMTZfR0xPQkFMX0VOCQlCSVQoMykNCj4gKw0KPiAr I2RlZmluZSBSRUdfMTdfQ0xLMzJNX0VOCQlCSVQoMCkNCj4gKw0KPiArI2RlZmluZSBSRUdfMl80 M19SQURJT19BX0VOCQlCSVQoMCkNCj4gKyNkZWZpbmUgUkVHXzJfNDNfUkFESU9fQl9FTgkJQklU KDEpDQo+ICsjZGVmaW5lIFJFR18yXzQzX1JBRElPX1JTVAkJQklUKDIpDQo+ICsNCj4gK3N0cnVj dCBzcGlfc3gxMzAxIHsNCj4gKwlzdHJ1Y3Qgc3BpX2RldmljZSAqcGFyZW50Ow0KPiArCXU4IHBh Z2U7DQo+ICsJdTggcmVnczsNCj4gK307DQo+ICsNCj4gK3N0cnVjdCBzeDEzMDFfcHJpdiB7DQo+ ICsJc3RydWN0IGxvcmFfcHJpdiBsb3JhOw0KPiArCXN0cnVjdCBncGlvX2Rlc2MgKnJzdF9ncGlv Ow0KPiArCXU4IGN1cl9wYWdlOw0KPiArCXN0cnVjdCBzcGlfY29udHJvbGxlciAqcmFkaW9fYV9j dHJsLCAqcmFkaW9fYl9jdHJsOw0KPiArfTsNCj4gKw0KPiArc3RhdGljIGludCBzeDEzMDFfcmVh ZChzdHJ1Y3Qgc3BpX2RldmljZSAqc3BpLCB1OCByZWcsIHU4ICp2YWwpDQo+ICt7DQo+ICsJdTgg YWRkciA9IHJlZyAmIDB4N2Y7DQo+ICsJcmV0dXJuIHNwaV93cml0ZV90aGVuX3JlYWQoc3BpLCAm YWRkciwgMSwgdmFsLCAxKTsNCj4gK30NCj4gKw0KPiArc3RhdGljIGludCBzeDEzMDFfd3JpdGUo c3RydWN0IHNwaV9kZXZpY2UgKnNwaSwgdTggcmVnLCB1OCB2YWwpDQo+ICt7DQo+ICsJdTggYnVm WzJdOw0KPiArDQo+ICsJYnVmWzBdID0gcmVnIHwgQklUKDcpOw0KPiArCWJ1ZlsxXSA9IHZhbDsN Cj4gKwlyZXR1cm4gc3BpX3dyaXRlKHNwaSwgYnVmLCAyKTsNCj4gK30NCj4gKw0KPiArc3RhdGlj IGludCBzeDEzMDFfcGFnZV9zd2l0Y2goc3RydWN0IHNwaV9kZXZpY2UgKnNwaSwgdTggcGFnZSkN Cj4gK3sNCj4gKwlzdHJ1Y3Qgc3gxMzAxX3ByaXYgKnByaXYgPSBzcGlfZ2V0X2RydmRhdGEoc3Bp KTsNCj4gKwlpbnQgcmV0Ow0KPiArDQo+ICsJaWYgKHByaXYtPmN1cl9wYWdlID09IHBhZ2UpDQo+ ICsJCXJldHVybiAwOw0KPiArDQo+ICsJZGV2X2RiZygmc3BpLT5kZXYsICJzd2l0Y2hpbmcgdG8g cGFnZSAldVxuIiwgKHVuc2lnbmVkKXBhZ2UpOw0KPiArCXJldCA9IHN4MTMwMV93cml0ZShzcGks IFJFR19QQUdFX1JFU0VULCBwYWdlICYgMHgzKTsNCj4gKwlpZiAocmV0KSB7DQo+ICsJCWRldl9l cnIoJnNwaS0+ZGV2LCAic3dpdGNoaW5nIHRvIHBhZ2UgJXUgZmFpbGVkXG4iLA0KPiAodW5zaWdu ZWQpcGFnZSk7DQo+ICsJCXJldHVybiByZXQ7DQo+ICsJfQ0KPiArDQo+ICsJcHJpdi0+Y3VyX3Bh Z2UgPSBwYWdlOw0KPiArDQo+ICsJcmV0dXJuIDA7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyBpbnQg c3gxMzAxX3NvZnRfcmVzZXQoc3RydWN0IHNwaV9kZXZpY2UgKnNwaSkNCj4gK3sNCj4gKwlyZXR1 cm4gc3gxMzAxX3dyaXRlKHNwaSwgUkVHX1BBR0VfUkVTRVQsDQo+IFJFR19QQUdFX1JFU0VUX1NP RlRfUkVTRVQpOw0KPiArfQ0KPiArDQo+ICsjZGVmaW5lIFJFR19SQURJT19YX0RBVEEJCTANCj4g KyNkZWZpbmUgUkVHX1JBRElPX1hfREFUQV9SRUFEQkFDSwkxDQo+ICsjZGVmaW5lIFJFR19SQURJ T19YX0FERFIJCTINCj4gKyNkZWZpbmUgUkVHX1JBRElPX1hfQ1MJCQk0DQo+ICsNCj4gK3N0YXRp YyBpbnQgc3gxMzAxX3JhZGlvX3NldF9jcyhzdHJ1Y3Qgc3BpX2NvbnRyb2xsZXIgKmN0cmwsIGJv b2wgZW5hYmxlKQ0KPiArew0KPiArCXN0cnVjdCBzcGlfc3gxMzAxICpzc3ggPSBzcGlfY29udHJv bGxlcl9nZXRfZGV2ZGF0YShjdHJsKTsNCj4gKwl1OCBjczsNCj4gKwlpbnQgcmV0Ow0KPiArDQo+ ICsJZGV2X2RiZygmY3RybC0+ZGV2LCAic2V0dGluZyBDUyB0byAlc1xuIiwgZW5hYmxlID8gIjEi IDogIjAiKTsNCj4gKw0KPiArCXJldCA9IHN4MTMwMV9wYWdlX3N3aXRjaChzc3gtPnBhcmVudCwg c3N4LT5wYWdlKTsNCj4gKwlpZiAocmV0KSB7DQo+ICsJCWRldl93YXJuKCZjdHJsLT5kZXYsICJm YWlsZWQgdG8gc3dpdGNoIHBhZ2UgZm9yIENTICglZClcbiIsDQo+IHJldCk7DQo+ICsJCXJldHVy biByZXQ7DQo+ICsJfQ0KPiArDQo+ICsJcmV0ID0gc3gxMzAxX3JlYWQoc3N4LT5wYXJlbnQsIHNz eC0+cmVncyArIFJFR19SQURJT19YX0NTLCAmY3MpOw0KPiArCWlmIChyZXQpIHsNCj4gKwkJZGV2 X3dhcm4oJmN0cmwtPmRldiwgImZhaWxlZCB0byByZWFkIENTICglZClcbiIsIHJldCk7DQo+ICsJ CWNzID0gMDsNCj4gKwl9DQo+ICsNCj4gKwlpZiAoZW5hYmxlKQ0KPiArCQljcyB8PSBCSVQoMCk7 DQo+ICsJZWxzZQ0KPiArCQljcyAmPSB+QklUKDApOw0KPiArDQo+ICsJcmV0ID0gc3gxMzAxX3dy aXRlKHNzeC0+cGFyZW50LCBzc3gtPnJlZ3MgKyBSRUdfUkFESU9fWF9DUywgY3MpOw0KPiArCWlm IChyZXQpDQo+ICsJCWRldl93YXJuKCZjdHJsLT5kZXYsICJmYWlsZWQgdG8gd3JpdGUgQ1MgKCVk KVxuIiwgcmV0KTsNCj4gKw0KPiArCXJldHVybiAwOw0KPiArfQ0KPiArDQo+ICtzdGF0aWMgdm9p ZCBzeDEzMDFfcmFkaW9fc3BpX3NldF9jcyhzdHJ1Y3Qgc3BpX2RldmljZSAqc3BpLCBib29sIGVu YWJsZSkNCj4gK3sNCj4gKwlpbnQgcmV0Ow0KPiArDQo+ICsJZGV2X2RiZygmc3BpLT5kZXYsICJz ZXR0aW5nIFNQSSBDUyB0byAlc1xuIiwgZW5hYmxlID8gIjEiIDogIjAiKTsNCj4gKw0KPiArCWlm IChlbmFibGUpDQo+ICsJCXJldHVybjsNCj4gKw0KPiArCXJldCA9IHN4MTMwMV9yYWRpb19zZXRf Y3Moc3BpLT5jb250cm9sbGVyLCBlbmFibGUpOw0KPiArCWlmIChyZXQpDQo+ICsJCWRldl93YXJu KCZzcGktPmRldiwgImZhaWxlZCB0byB3cml0ZSBDUyAoJWQpXG4iLCByZXQpOw0KPiArfQ0KPiAr DQo+ICtzdGF0aWMgaW50IHN4MTMwMV9yYWRpb19zcGlfdHJhbnNmZXJfb25lKHN0cnVjdCBzcGlf Y29udHJvbGxlciAqY3RybCwNCj4gKwlzdHJ1Y3Qgc3BpX2RldmljZSAqc3BpLCBzdHJ1Y3Qgc3Bp X3RyYW5zZmVyICp4ZnIpDQo+ICt7DQo+ICsJc3RydWN0IHNwaV9zeDEzMDEgKnNzeCA9IHNwaV9j b250cm9sbGVyX2dldF9kZXZkYXRhKGN0cmwpOw0KPiArCWNvbnN0IHU4ICp0eF9idWYgPSB4ZnIt PnR4X2J1ZjsNCj4gKwl1OCAqcnhfYnVmID0geGZyLT5yeF9idWY7DQo+ICsJaW50IHJldDsNCj4g Kw0KPiArCWlmICh4ZnItPmxlbiA9PSAwIHx8IHhmci0+bGVuID4gMykNCj4gKwkJcmV0dXJuIC1F SU5WQUw7DQo+ICsNCj4gKwlkZXZfZGJnKCZzcGktPmRldiwgInRyYW5zZmVycmluZyBvbmUgKCV1 KVxuIiwgeGZyLT5sZW4pOw0KPiArDQo+ICsJcmV0ID0gc3gxMzAxX3BhZ2Vfc3dpdGNoKHNzeC0+ cGFyZW50LCBzc3gtPnBhZ2UpOw0KPiArCWlmIChyZXQpIHsNCj4gKwkJZGV2X2Vycigmc3BpLT5k ZXYsICJmYWlsZWQgdG8gc3dpdGNoIHBhZ2UgZm9yIHRyYW5zZmVyDQo+ICglZClcbiIsIHJldCk7 DQo+ICsJCXJldHVybiByZXQ7DQo+ICsJfQ0KPiArDQo+ICsJaWYgKHR4X2J1Zikgew0KPiArCQly ZXQgPSBzeDEzMDFfd3JpdGUoc3N4LT5wYXJlbnQsIHNzeC0+cmVncyArDQo+IFJFR19SQURJT19Y X0FERFIsIHR4X2J1ZiA/IHR4X2J1ZlswXSA6IDApOw0KPiArCQlpZiAocmV0KSB7DQo+ICsJCQlk ZXZfZXJyKCZzcGktPmRldiwgIlNQSSByYWRpbyBhZGRyZXNzIHdyaXRlDQo+IGZhaWxlZFxuIik7 DQo+ICsJCQlyZXR1cm4gcmV0Ow0KPiArCQl9DQo+ICsNCj4gKwkJcmV0ID0gc3gxMzAxX3dyaXRl KHNzeC0+cGFyZW50LCBzc3gtPnJlZ3MgKw0KPiBSRUdfUkFESU9fWF9EQVRBLCAodHhfYnVmICYm IHhmci0+bGVuID49IDIpID8gdHhfYnVmWzFdIDogMCk7DQo+ICsJCWlmIChyZXQpIHsNCj4gKwkJ CWRldl9lcnIoJnNwaS0+ZGV2LCAiU1BJIHJhZGlvIGRhdGEgd3JpdGUgZmFpbGVkXG4iKTsNCj4g KwkJCXJldHVybiByZXQ7DQo+ICsJCX0NCj4gKw0KPiArCQlyZXQgPSBzeDEzMDFfcmFkaW9fc2V0 X2NzKGN0cmwsIHRydWUpOw0KPiArCQlpZiAocmV0KSB7DQo+ICsJCQlkZXZfZXJyKCZzcGktPmRl diwgIlNQSSByYWRpbyBDUyBzZXQgZmFpbGVkXG4iKTsNCj4gKwkJCXJldHVybiByZXQ7DQo+ICsJ CX0NCj4gKw0KPiArCQlyZXQgPSBzeDEzMDFfcmFkaW9fc2V0X2NzKGN0cmwsIGZhbHNlKTsNCj4g KwkJaWYgKHJldCkgew0KPiArCQkJZGV2X2Vycigmc3BpLT5kZXYsICJTUEkgcmFkaW8gQ1MgdW5z ZXQgZmFpbGVkXG4iKTsNCj4gKwkJCXJldHVybiByZXQ7DQo+ICsJCX0NCj4gKwl9DQo+ICsNCj4g KwlpZiAocnhfYnVmKSB7DQo+ICsJCXJldCA9IHN4MTMwMV9yZWFkKHNzeC0+cGFyZW50LCBzc3gt PnJlZ3MgKw0KPiBSRUdfUkFESU9fWF9EQVRBX1JFQURCQUNLLCAmcnhfYnVmW3hmci0+bGVuIC0g MV0pOw0KPiArCQlpZiAocmV0KSB7DQo+ICsJCQlkZXZfZXJyKCZzcGktPmRldiwgIlNQSSByYWRp byBkYXRhIHJlYWQgZmFpbGVkXG4iKTsNCj4gKwkJCXJldHVybiByZXQ7DQo+ICsJCX0NCj4gKwl9 DQo+ICsNCj4gKwlyZXR1cm4gMDsNCj4gK30NCj4gKw0KPiArc3RhdGljIHZvaWQgc3gxMzAxX3Jh ZGlvX3NldHVwKHN0cnVjdCBzcGlfY29udHJvbGxlciAqY3RybCkNCj4gK3sNCj4gKwljdHJsLT5t b2RlX2JpdHMgPSBTUElfQ1NfSElHSCB8IFNQSV9OT19DUzsNCj4gKwljdHJsLT5iaXRzX3Blcl93 b3JkX21hc2sgPSBTUElfQlBXX01BU0soOCk7DQo+ICsJY3RybC0+bnVtX2NoaXBzZWxlY3QgPSAx Ow0KPiArCWN0cmwtPnNldF9jcyA9IHN4MTMwMV9yYWRpb19zcGlfc2V0X2NzOw0KPiArCWN0cmwt PnRyYW5zZmVyX29uZSA9IHN4MTMwMV9yYWRpb19zcGlfdHJhbnNmZXJfb25lOw0KPiArfQ0KPiAr DQo+ICtzdGF0aWMgaW50IHN4MTMwMV9wcm9iZShzdHJ1Y3Qgc3BpX2RldmljZSAqc3BpKQ0KPiAr ew0KPiArCXN0cnVjdCBuZXRfZGV2aWNlICpuZXRkZXY7DQo+ICsJc3RydWN0IHN4MTMwMV9wcml2 ICpwcml2Ow0KPiArCXN0cnVjdCBzcGlfc3gxMzAxICpyYWRpbzsNCj4gKwlzdHJ1Y3QgZ3Bpb19k ZXNjICpyc3Q7DQo+ICsJaW50IHJldDsNCj4gKwl1OCB2YWw7DQo+ICsNCj4gKwlyc3QgPSBkZXZt X2dwaW9kX2dldF9vcHRpb25hbCgmc3BpLT5kZXYsICJyZXNldCIsDQo+IEdQSU9EX09VVF9MT1cp Ow0KPiArCWlmIChJU19FUlIocnN0KSkNCj4gKwkJcmV0dXJuIFBUUl9FUlIocnN0KTsNCj4gKw0K PiArCWdwaW9kX3NldF92YWx1ZV9jYW5zbGVlcChyc3QsIDEpOw0KPiArCW1zbGVlcCgxMDApOw0K PiArCWdwaW9kX3NldF92YWx1ZV9jYW5zbGVlcChyc3QsIDApOw0KPiArCW1zbGVlcCgxMDApOw0K PiArDQo+ICsJc3BpLT5iaXRzX3Blcl93b3JkID0gODsNCj4gKwlzcGlfc2V0dXAoc3BpKTsNCj4g Kw0KPiArCXJldCA9IHN4MTMwMV9yZWFkKHNwaSwgUkVHX1ZFUlNJT04sICZ2YWwpOw0KPiArCWlm IChyZXQpIHsNCj4gKwkJZGV2X2Vycigmc3BpLT5kZXYsICJ2ZXJzaW9uIHJlYWQgZmFpbGVkXG4i KTsNCj4gKwkJZ290byBlcnJfdmVyc2lvbjsNCj4gKwl9DQo+ICsNCj4gKwlpZiAodmFsICE9IDEw Mykgew0KPiArCQlkZXZfZXJyKCZzcGktPmRldiwgInVuZXhwZWN0ZWQgdmVyc2lvbjogJXVcbiIs IHZhbCk7DQo+ICsJCXJldCA9IC1FTlhJTzsNCj4gKwkJZ290byBlcnJfdmVyc2lvbjsNCj4gKwl9 DQo+ICsNCj4gKwluZXRkZXYgPSBhbGxvY19sb3JhZGV2KHNpemVvZigqcHJpdikpOw0KPiArCWlm ICghbmV0ZGV2KSB7DQo+ICsJCXJldCA9IC1FTk9NRU07DQo+ICsJCWdvdG8gZXJyX2FsbG9jX2xv cmFkZXY7DQo+ICsJfQ0KPiArDQo+ICsJcHJpdiA9IG5ldGRldl9wcml2KG5ldGRldik7DQo+ICsJ cHJpdi0+cnN0X2dwaW8gPSByc3Q7DQo+ICsJcHJpdi0+Y3VyX3BhZ2UgPSAweGZmOw0KPiArDQo+ ICsJc3BpX3NldF9kcnZkYXRhKHNwaSwgbmV0ZGV2KTsNCj4gKwlTRVRfTkVUREVWX0RFVihuZXRk ZXYsICZzcGktPmRldik7DQo+ICsNCj4gKwlyZXQgPSBzeDEzMDFfd3JpdGUoc3BpLCBSRUdfUEFH RV9SRVNFVCwgMCk7DQo+ICsJaWYgKHJldCkgew0KPiArCQlkZXZfZXJyKCZzcGktPmRldiwgInBh Z2UvcmVzZXQgd3JpdGUgZmFpbGVkXG4iKTsNCj4gKwkJcmV0dXJuIHJldDsNCj4gKwl9DQo+ICsN Cj4gKwlyZXQgPSBzeDEzMDFfc29mdF9yZXNldChzcGkpOw0KPiArCWlmIChyZXQpIHsNCj4gKwkJ ZGV2X2Vycigmc3BpLT5kZXYsICJzb2Z0IHJlc2V0IGZhaWxlZFxuIik7DQo+ICsJCXJldHVybiBy ZXQ7DQo+ICsJfQ0KPiArDQo+ICsJcmV0ID0gc3gxMzAxX3JlYWQoc3BpLCAxNiwgJnZhbCk7DQo+ ICsJaWYgKHJldCkgew0KPiArCQlkZXZfZXJyKCZzcGktPmRldiwgIjE2IHJlYWQgZmFpbGVkXG4i KTsNCj4gKwkJcmV0dXJuIHJldDsNCj4gKwl9DQo+ICsNCj4gKwl2YWwgJj0gflJFR18xNl9HTE9C QUxfRU47DQo+ICsNCj4gKwlyZXQgPSBzeDEzMDFfd3JpdGUoc3BpLCAxNiwgdmFsKTsNCj4gKwlp ZiAocmV0KSB7DQo+ICsJCWRldl9lcnIoJnNwaS0+ZGV2LCAiMTYgd3JpdGUgZmFpbGVkXG4iKTsN Cj4gKwkJcmV0dXJuIHJldDsNCj4gKwl9DQo+ICsNCj4gKwlyZXQgPSBzeDEzMDFfcmVhZChzcGks IDE3LCAmdmFsKTsNCj4gKwlpZiAocmV0KSB7DQo+ICsJCWRldl9lcnIoJnNwaS0+ZGV2LCAiMTcg cmVhZCBmYWlsZWRcbiIpOw0KPiArCQlyZXR1cm4gcmV0Ow0KPiArCX0NCj4gKw0KPiArCXZhbCAm PSB+UkVHXzE3X0NMSzMyTV9FTjsNCj4gKw0KPiArCXJldCA9IHN4MTMwMV93cml0ZShzcGksIDE3 LCB2YWwpOw0KPiArCWlmIChyZXQpIHsNCj4gKwkJZGV2X2Vycigmc3BpLT5kZXYsICIxNyB3cml0 ZSBmYWlsZWRcbiIpOw0KPiArCQlyZXR1cm4gcmV0Ow0KPiArCX0NCj4gKw0KPiArCXJldCA9IHN4 MTMwMV9wYWdlX3N3aXRjaChzcGksIDIpOw0KPiArCWlmIChyZXQpIHsNCj4gKwkJZGV2X2Vycigm c3BpLT5kZXYsICJwYWdlIDIgc3dpdGNoIGZhaWxlZFxuIik7DQo+ICsJCXJldHVybiByZXQ7DQo+ ICsJfQ0KPiArDQo+ICsJcmV0ID0gc3gxMzAxX3JlYWQoc3BpLCA0MywgJnZhbCk7DQo+ICsJaWYg KHJldCkgew0KPiArCQlkZXZfZXJyKCZzcGktPmRldiwgIjJ8NDMgcmVhZCBmYWlsZWRcbiIpOw0K PiArCQlyZXR1cm4gcmV0Ow0KPiArCX0NCj4gKw0KPiArCXZhbCB8PSBSRUdfMl80M19SQURJT19C X0VOIHwgUkVHXzJfNDNfUkFESU9fQV9FTjsNCj4gKw0KPiArCXJldCA9IHN4MTMwMV93cml0ZShz cGksIDQzLCB2YWwpOw0KPiArCWlmIChyZXQpIHsNCj4gKwkJZGV2X2Vycigmc3BpLT5kZXYsICIy fDQzIHdyaXRlIGZhaWxlZFxuIik7DQo+ICsJCXJldHVybiByZXQ7DQo+ICsJfQ0KPiArDQo+ICsJ bXNsZWVwKDUwMCk7DQo+ICsNCj4gKwlyZXQgPSBzeDEzMDFfcmVhZChzcGksIDQzLCAmdmFsKTsN Cj4gKwlpZiAocmV0KSB7DQo+ICsJCWRldl9lcnIoJnNwaS0+ZGV2LCAiMnw0MyByZWFkIGZhaWxl ZFxuIik7DQo+ICsJCXJldHVybiByZXQ7DQo+ICsJfQ0KPiArDQo+ICsJdmFsIHw9IFJFR18yXzQz X1JBRElPX1JTVDsNCj4gKw0KPiArCXJldCA9IHN4MTMwMV93cml0ZShzcGksIDQzLCB2YWwpOw0K PiArCWlmIChyZXQpIHsNCj4gKwkJZGV2X2Vycigmc3BpLT5kZXYsICIyfDQzIHdyaXRlIGZhaWxl ZFxuIik7DQo+ICsJCXJldHVybiByZXQ7DQo+ICsJfQ0KPiArDQo+ICsJbXNsZWVwKDUpOw0KPiAr DQo+ICsJcmV0ID0gc3gxMzAxX3JlYWQoc3BpLCA0MywgJnZhbCk7DQo+ICsJaWYgKHJldCkgew0K PiArCQlkZXZfZXJyKCZzcGktPmRldiwgIjJ8NDMgcmVhZCBmYWlsZWRcbiIpOw0KPiArCQlyZXR1 cm4gcmV0Ow0KPiArCX0NCj4gKw0KPiArCXZhbCAmPSB+UkVHXzJfNDNfUkFESU9fUlNUOw0KPiAr DQo+ICsJcmV0ID0gc3gxMzAxX3dyaXRlKHNwaSwgNDMsIHZhbCk7DQo+ICsJaWYgKHJldCkgew0K PiArCQlkZXZfZXJyKCZzcGktPmRldiwgIjJ8NDMgd3JpdGUgZmFpbGVkXG4iKTsNCj4gKwkJcmV0 dXJuIHJldDsNCj4gKwl9DQo+ICsNCj4gKwkvKiByYWRpbyBBICovDQo+ICsNCj4gKwlwcml2LT5y YWRpb19hX2N0cmwgPSBzcGlfYWxsb2NfbWFzdGVyKCZzcGktPmRldiwgc2l6ZW9mKCpyYWRpbykp Ow0KPiArCWlmICghcHJpdi0+cmFkaW9fYV9jdHJsKSB7DQo+ICsJCXJldCA9IC1FTk9NRU07DQo+ ICsJCWdvdG8gZXJyX3JhZGlvX2FfYWxsb2M7DQo+ICsJfQ0KPiArDQo+ICsJc3gxMzAxX3JhZGlv X3NldHVwKHByaXYtPnJhZGlvX2FfY3RybCk7DQo+ICsJcHJpdi0+cmFkaW9fYV9jdHJsLT5kZXYu b2Zfbm9kZSA9IG9mX2dldF9jaGlsZF9ieV9uYW1lKHNwaS0NCj4gPmRldi5vZl9ub2RlLCAicmFk aW8tYSIpOw0KPiArDQo+ICsJcmFkaW8gPSBzcGlfY29udHJvbGxlcl9nZXRfZGV2ZGF0YShwcml2 LT5yYWRpb19hX2N0cmwpOw0KPiArCXJhZGlvLT5wYWdlID0gMjsNCj4gKwlyYWRpby0+cmVncyA9 IFJFR18yX1NQSV9SQURJT19BX0RBVEE7DQo+ICsJcmFkaW8tPnBhcmVudCA9IHNwaTsNCj4gKw0K PiArCWRldl9pbmZvKCZzcGktPmRldiwgInJlZ2lzdGVyaW5nIHJhZGlvIEEgU1BJXG4iKTsNCj4g Kw0KPiArCXJldCA9IGRldm1fc3BpX3JlZ2lzdGVyX2NvbnRyb2xsZXIoJnNwaS0+ZGV2LCBwcml2 LT5yYWRpb19hX2N0cmwpOw0KPiArCWlmIChyZXQpIHsNCj4gKwkJZGV2X2Vycigmc3BpLT5kZXYs ICJyYWRpbyBBIFNQSSByZWdpc3RlciBmYWlsZWRcbiIpOw0KPiArCQlnb3RvIGVycl9yYWRpb19h X3JlZ2lzdGVyOw0KPiArCX0NCj4gKw0KPiArCS8qIHJhZGlvIEIgKi8NCj4gKw0KPiArCXByaXYt PnJhZGlvX2JfY3RybCA9IHNwaV9hbGxvY19tYXN0ZXIoJnNwaS0+ZGV2LCBzaXplb2YoKnJhZGlv KSk7DQo+ICsJaWYgKCFwcml2LT5yYWRpb19iX2N0cmwpIHsNCj4gKwkJcmV0ID0gLUVOT01FTTsN Cj4gKwkJZ290byBlcnJfcmFkaW9fYl9hbGxvYzsNCj4gKwl9DQo+ICsNCj4gKwlzeDEzMDFfcmFk aW9fc2V0dXAocHJpdi0+cmFkaW9fYl9jdHJsKTsNCj4gKwlwcml2LT5yYWRpb19iX2N0cmwtPmRl di5vZl9ub2RlID0gb2ZfZ2V0X2NoaWxkX2J5X25hbWUoc3BpLQ0KPiA+ZGV2Lm9mX25vZGUsICJy YWRpby1iIik7DQo+ICsNCj4gKwlyYWRpbyA9IHNwaV9jb250cm9sbGVyX2dldF9kZXZkYXRhKHBy aXYtPnJhZGlvX2JfY3RybCk7DQo+ICsJcmFkaW8tPnBhZ2UgPSAyOw0KPiArCXJhZGlvLT5yZWdz ID0gUkVHXzJfU1BJX1JBRElPX0JfREFUQTsNCj4gKwlyYWRpby0+cGFyZW50ID0gc3BpOw0KPiAr DQo+ICsJZGV2X2luZm8oJnNwaS0+ZGV2LCAicmVnaXN0ZXJpbmcgcmFkaW8gQiBTUElcbiIpOw0K PiArDQo+ICsJcmV0ID0gZGV2bV9zcGlfcmVnaXN0ZXJfY29udHJvbGxlcigmc3BpLT5kZXYsIHBy aXYtPnJhZGlvX2JfY3RybCk7DQo+ICsJaWYgKHJldCkgew0KPiArCQlkZXZfZXJyKCZzcGktPmRl diwgInJhZGlvIEIgU1BJIHJlZ2lzdGVyIGZhaWxlZFxuIik7DQo+ICsJCWdvdG8gZXJyX3JhZGlv X2JfcmVnaXN0ZXI7DQo+ICsJfQ0KPiArDQo+ICsJZGV2X2luZm8oJnNwaS0+ZGV2LCAiU1gxMzAx IG1vZHVsZSBwcm9iZWRcbiIpOw0KPiArDQo+ICsJcmV0dXJuIDA7DQo+ICtlcnJfcmFkaW9fYl9y ZWdpc3RlcjoNCj4gKwlzcGlfY29udHJvbGxlcl9wdXQocHJpdi0+cmFkaW9fYl9jdHJsKTsNCj4g K2Vycl9yYWRpb19iX2FsbG9jOg0KPiArZXJyX3JhZGlvX2FfcmVnaXN0ZXI6DQo+ICsJc3BpX2Nv bnRyb2xsZXJfcHV0KHByaXYtPnJhZGlvX2FfY3RybCk7DQo+ICtlcnJfcmFkaW9fYV9hbGxvYzoN Cj4gKwlmcmVlX2xvcmFkZXYobmV0ZGV2KTsNCj4gK2Vycl9hbGxvY19sb3JhZGV2Og0KPiArZXJy X3ZlcnNpb246DQo+ICsJcmV0dXJuIHJldDsNCj4gK30NCj4gKw0KPiArc3RhdGljIGludCBzeDEz MDFfcmVtb3ZlKHN0cnVjdCBzcGlfZGV2aWNlICpzcGkpDQo+ICt7DQo+ICsJc3RydWN0IG5ldF9k ZXZpY2UgKm5ldGRldiA9IHNwaV9nZXRfZHJ2ZGF0YShzcGkpOw0KPiArDQo+ICsJLy91bnJlZ2lz dGVyX2xvcmFkZXYobmV0ZGV2KTsNCj4gKwlmcmVlX2xvcmFkZXYobmV0ZGV2KTsNCj4gKw0KPiAr CWRldl9pbmZvKCZzcGktPmRldiwgIlNYMTMwMSBtb2R1bGUgcmVtb3ZlZFxuIik7DQo+ICsNCj4g KwlyZXR1cm4gMDsNCj4gK30NCj4gKw0KPiArI2lmZGVmIENPTkZJR19PRg0KPiArc3RhdGljIGNv bnN0IHN0cnVjdCBvZl9kZXZpY2VfaWQgc3gxMzAxX2R0X2lkc1tdID0gew0KPiArCXsgLmNvbXBh dGlibGUgPSAic2VtdGVjaCxzeDEzMDEiIH0sDQo+ICsJe30NCj4gK307DQo+ICtNT0RVTEVfREVW SUNFX1RBQkxFKG9mLCBzeDEzMDFfZHRfaWRzKTsNCj4gKyNlbmRpZg0KPiArDQo+ICtzdGF0aWMg c3RydWN0IHNwaV9kcml2ZXIgc3gxMzAxX3NwaV9kcml2ZXIgPSB7DQo+ICsJLmRyaXZlciA9IHsN Cj4gKwkJLm5hbWUgPSAic3gxMzAxIiwNCj4gKwkJLm9mX21hdGNoX3RhYmxlID0gb2ZfbWF0Y2hf cHRyKHN4MTMwMV9kdF9pZHMpLA0KPiArCX0sDQo+ICsJLnByb2JlID0gc3gxMzAxX3Byb2JlLA0K PiArCS5yZW1vdmUgPSBzeDEzMDFfcmVtb3ZlLA0KPiArfTsNCj4gKw0KPiArbW9kdWxlX3NwaV9k cml2ZXIoc3gxMzAxX3NwaV9kcml2ZXIpOw0KPiArDQo+ICtNT0RVTEVfREVTQ1JJUFRJT04oIlNY MTMwMSBTUEkgZHJpdmVyIik7DQo+ICtNT0RVTEVfQVVUSE9SKCJBbmRyZWFzIEbDpHJiZXIgPGFm YWVyYmVyQHN1c2UuZGU+Iik7DQo+ICtNT0RVTEVfTElDRU5TRSgiR1BMIik7DQo+IC0tDQo+IDIu MTYuNA0KDQo= From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ben.Whitten@lairdtech.com (Ben Whitten) Date: Mon, 2 Jul 2018 11:51:19 +0000 Subject: [RFC net-next 15/15] net: lora: Add Semtech SX1301 In-Reply-To: <20180701110804.32415-16-afaerber@suse.de> References: <20180701110804.32415-1-afaerber@suse.de> <20180701110804.32415-16-afaerber@suse.de> Message-ID: To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Hi Andreas, Excellent work on doing this I have also been working on and off this personally for some time. Have a look at my repository [1] for sx1301 and sx1257 drivers, I use regmaps capability of switching pages which should simplify your driver considerably, I also have a full register map and bit field. I have also been trying to use the clk framework to capture the various routing that the cards have. I will dig into this series this evening. [1] https://github.com/BWhitten/linux-stable/tree/971aadc8fdfe842020d912449bdd71b33d576fe3/drivers/net/lora > Subject: [RFC net-next 15/15] net: lora: Add Semtech SX1301 > > The Semtech SX1301 was the first multi-channel LoRa "concentrator". > It uses a SPI interface to the host as well as a dual SPI interface to > its radios. These two have been implemented as spi_controller, so that > the Device Tree can specify whether the respective module uses two > SX1257, two SX1255 or a combination of these or some unforeseen chipset. > > This implementation is the most recent - initialization is not yet > complete, it will need to load firmware into the two on-chip MCUs. > > Unfortunately there is no full datasheet with register descriptions, > only a BSD-licensed userspace HAL implementation using spidev devices. > Therefore some register names are unknown. > > Cc: Ben Whitten > Cc: Steve deRosier > Cc: Mark Brown > Cc: Michael R?der > Cc: Ken Yu (??) > Cc: linux-spi at vger.kernel.org > Signed-off-by: Andreas F?rber > --- > drivers/net/lora/Kconfig | 7 + > drivers/net/lora/Makefile | 3 + > drivers/net/lora/sx1301.c | 446 > ++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 456 insertions(+) > create mode 100644 drivers/net/lora/sx1301.c > > diff --git a/drivers/net/lora/Kconfig b/drivers/net/lora/Kconfig > index 68c7480d7812..950450e353b4 100644 > --- a/drivers/net/lora/Kconfig > +++ b/drivers/net/lora/Kconfig > @@ -45,6 +45,13 @@ config LORA_SX1276 > help > Semtech SX1272/1276/1278 > > +config LORA_SX1301 > + tristate "Semtech SX1301 SPI driver" > + default y > + depends on SPI > + help > + Semtech SX1301 > + > config LORA_USI > tristate "USI WM-SG-SM-42 driver" > default y > diff --git a/drivers/net/lora/Makefile b/drivers/net/lora/Makefile > index 44c578bde7d5..1cc1e3aa189b 100644 > --- a/drivers/net/lora/Makefile > +++ b/drivers/net/lora/Makefile > @@ -22,6 +22,9 @@ lora-sx1257-y := sx1257.o > obj-$(CONFIG_LORA_SX1276) += lora-sx1276.o > lora-sx1276-y := sx1276.o > > +obj-$(CONFIG_LORA_SX1301) += lora-sx1301.o > +lora-sx1301-y := sx1301.o > + > obj-$(CONFIG_LORA_USI) += lora-usi.o > lora-usi-y := usi.o > > diff --git a/drivers/net/lora/sx1301.c b/drivers/net/lora/sx1301.c > new file mode 100644 > index 000000000000..5c936c1116d1 > --- /dev/null > +++ b/drivers/net/lora/sx1301.c > @@ -0,0 +1,446 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * Semtech SX1301 LoRa concentrator > + * > + * Copyright (c) 2018 Andreas F?rber > + * > + * Based on SX1301 HAL code: > + * Copyright (c) 2013 Semtech-Cycleo > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define REG_PAGE_RESET 0 > +#define REG_VERSION 1 > +#define REG_2_SPI_RADIO_A_DATA 33 > +#define REG_2_SPI_RADIO_A_DATA_READBACK 34 > +#define REG_2_SPI_RADIO_A_ADDR 35 > +#define REG_2_SPI_RADIO_A_CS 37 > +#define REG_2_SPI_RADIO_B_DATA 38 > +#define REG_2_SPI_RADIO_B_DATA_READBACK 39 > +#define REG_2_SPI_RADIO_B_ADDR 40 > +#define REG_2_SPI_RADIO_B_CS 42 > + > +#define REG_PAGE_RESET_SOFT_RESET BIT(7) > + > +#define REG_16_GLOBAL_EN BIT(3) > + > +#define REG_17_CLK32M_EN BIT(0) > + > +#define REG_2_43_RADIO_A_EN BIT(0) > +#define REG_2_43_RADIO_B_EN BIT(1) > +#define REG_2_43_RADIO_RST BIT(2) > + > +struct spi_sx1301 { > + struct spi_device *parent; > + u8 page; > + u8 regs; > +}; > + > +struct sx1301_priv { > + struct lora_priv lora; > + struct gpio_desc *rst_gpio; > + u8 cur_page; > + struct spi_controller *radio_a_ctrl, *radio_b_ctrl; > +}; > + > +static int sx1301_read(struct spi_device *spi, u8 reg, u8 *val) > +{ > + u8 addr = reg & 0x7f; > + return spi_write_then_read(spi, &addr, 1, val, 1); > +} > + > +static int sx1301_write(struct spi_device *spi, u8 reg, u8 val) > +{ > + u8 buf[2]; > + > + buf[0] = reg | BIT(7); > + buf[1] = val; > + return spi_write(spi, buf, 2); > +} > + > +static int sx1301_page_switch(struct spi_device *spi, u8 page) > +{ > + struct sx1301_priv *priv = spi_get_drvdata(spi); > + int ret; > + > + if (priv->cur_page == page) > + return 0; > + > + dev_dbg(&spi->dev, "switching to page %u\n", (unsigned)page); > + ret = sx1301_write(spi, REG_PAGE_RESET, page & 0x3); > + if (ret) { > + dev_err(&spi->dev, "switching to page %u failed\n", > (unsigned)page); > + return ret; > + } > + > + priv->cur_page = page; > + > + return 0; > +} > + > +static int sx1301_soft_reset(struct spi_device *spi) > +{ > + return sx1301_write(spi, REG_PAGE_RESET, > REG_PAGE_RESET_SOFT_RESET); > +} > + > +#define REG_RADIO_X_DATA 0 > +#define REG_RADIO_X_DATA_READBACK 1 > +#define REG_RADIO_X_ADDR 2 > +#define REG_RADIO_X_CS 4 > + > +static int sx1301_radio_set_cs(struct spi_controller *ctrl, bool enable) > +{ > + struct spi_sx1301 *ssx = spi_controller_get_devdata(ctrl); > + u8 cs; > + int ret; > + > + dev_dbg(&ctrl->dev, "setting CS to %s\n", enable ? "1" : "0"); > + > + ret = sx1301_page_switch(ssx->parent, ssx->page); > + if (ret) { > + dev_warn(&ctrl->dev, "failed to switch page for CS (%d)\n", > ret); > + return ret; > + } > + > + ret = sx1301_read(ssx->parent, ssx->regs + REG_RADIO_X_CS, &cs); > + if (ret) { > + dev_warn(&ctrl->dev, "failed to read CS (%d)\n", ret); > + cs = 0; > + } > + > + if (enable) > + cs |= BIT(0); > + else > + cs &= ~BIT(0); > + > + ret = sx1301_write(ssx->parent, ssx->regs + REG_RADIO_X_CS, cs); > + if (ret) > + dev_warn(&ctrl->dev, "failed to write CS (%d)\n", ret); > + > + return 0; > +} > + > +static void sx1301_radio_spi_set_cs(struct spi_device *spi, bool enable) > +{ > + int ret; > + > + dev_dbg(&spi->dev, "setting SPI CS to %s\n", enable ? "1" : "0"); > + > + if (enable) > + return; > + > + ret = sx1301_radio_set_cs(spi->controller, enable); > + if (ret) > + dev_warn(&spi->dev, "failed to write CS (%d)\n", ret); > +} > + > +static int sx1301_radio_spi_transfer_one(struct spi_controller *ctrl, > + struct spi_device *spi, struct spi_transfer *xfr) > +{ > + struct spi_sx1301 *ssx = spi_controller_get_devdata(ctrl); > + const u8 *tx_buf = xfr->tx_buf; > + u8 *rx_buf = xfr->rx_buf; > + int ret; > + > + if (xfr->len == 0 || xfr->len > 3) > + return -EINVAL; > + > + dev_dbg(&spi->dev, "transferring one (%u)\n", xfr->len); > + > + ret = sx1301_page_switch(ssx->parent, ssx->page); > + if (ret) { > + dev_err(&spi->dev, "failed to switch page for transfer > (%d)\n", ret); > + return ret; > + } > + > + if (tx_buf) { > + ret = sx1301_write(ssx->parent, ssx->regs + > REG_RADIO_X_ADDR, tx_buf ? tx_buf[0] : 0); > + if (ret) { > + dev_err(&spi->dev, "SPI radio address write > failed\n"); > + return ret; > + } > + > + ret = sx1301_write(ssx->parent, ssx->regs + > REG_RADIO_X_DATA, (tx_buf && xfr->len >= 2) ? tx_buf[1] : 0); > + if (ret) { > + dev_err(&spi->dev, "SPI radio data write failed\n"); > + return ret; > + } > + > + ret = sx1301_radio_set_cs(ctrl, true); > + if (ret) { > + dev_err(&spi->dev, "SPI radio CS set failed\n"); > + return ret; > + } > + > + ret = sx1301_radio_set_cs(ctrl, false); > + if (ret) { > + dev_err(&spi->dev, "SPI radio CS unset failed\n"); > + return ret; > + } > + } > + > + if (rx_buf) { > + ret = sx1301_read(ssx->parent, ssx->regs + > REG_RADIO_X_DATA_READBACK, &rx_buf[xfr->len - 1]); > + if (ret) { > + dev_err(&spi->dev, "SPI radio data read failed\n"); > + return ret; > + } > + } > + > + return 0; > +} > + > +static void sx1301_radio_setup(struct spi_controller *ctrl) > +{ > + ctrl->mode_bits = SPI_CS_HIGH | SPI_NO_CS; > + ctrl->bits_per_word_mask = SPI_BPW_MASK(8); > + ctrl->num_chipselect = 1; > + ctrl->set_cs = sx1301_radio_spi_set_cs; > + ctrl->transfer_one = sx1301_radio_spi_transfer_one; > +} > + > +static int sx1301_probe(struct spi_device *spi) > +{ > + struct net_device *netdev; > + struct sx1301_priv *priv; > + struct spi_sx1301 *radio; > + struct gpio_desc *rst; > + int ret; > + u8 val; > + > + rst = devm_gpiod_get_optional(&spi->dev, "reset", > GPIOD_OUT_LOW); > + if (IS_ERR(rst)) > + return PTR_ERR(rst); > + > + gpiod_set_value_cansleep(rst, 1); > + msleep(100); > + gpiod_set_value_cansleep(rst, 0); > + msleep(100); > + > + spi->bits_per_word = 8; > + spi_setup(spi); > + > + ret = sx1301_read(spi, REG_VERSION, &val); > + if (ret) { > + dev_err(&spi->dev, "version read failed\n"); > + goto err_version; > + } > + > + if (val != 103) { > + dev_err(&spi->dev, "unexpected version: %u\n", val); > + ret = -ENXIO; > + goto err_version; > + } > + > + netdev = alloc_loradev(sizeof(*priv)); > + if (!netdev) { > + ret = -ENOMEM; > + goto err_alloc_loradev; > + } > + > + priv = netdev_priv(netdev); > + priv->rst_gpio = rst; > + priv->cur_page = 0xff; > + > + spi_set_drvdata(spi, netdev); > + SET_NETDEV_DEV(netdev, &spi->dev); > + > + ret = sx1301_write(spi, REG_PAGE_RESET, 0); > + if (ret) { > + dev_err(&spi->dev, "page/reset write failed\n"); > + return ret; > + } > + > + ret = sx1301_soft_reset(spi); > + if (ret) { > + dev_err(&spi->dev, "soft reset failed\n"); > + return ret; > + } > + > + ret = sx1301_read(spi, 16, &val); > + if (ret) { > + dev_err(&spi->dev, "16 read failed\n"); > + return ret; > + } > + > + val &= ~REG_16_GLOBAL_EN; > + > + ret = sx1301_write(spi, 16, val); > + if (ret) { > + dev_err(&spi->dev, "16 write failed\n"); > + return ret; > + } > + > + ret = sx1301_read(spi, 17, &val); > + if (ret) { > + dev_err(&spi->dev, "17 read failed\n"); > + return ret; > + } > + > + val &= ~REG_17_CLK32M_EN; > + > + ret = sx1301_write(spi, 17, val); > + if (ret) { > + dev_err(&spi->dev, "17 write failed\n"); > + return ret; > + } > + > + ret = sx1301_page_switch(spi, 2); > + if (ret) { > + dev_err(&spi->dev, "page 2 switch failed\n"); > + return ret; > + } > + > + ret = sx1301_read(spi, 43, &val); > + if (ret) { > + dev_err(&spi->dev, "2|43 read failed\n"); > + return ret; > + } > + > + val |= REG_2_43_RADIO_B_EN | REG_2_43_RADIO_A_EN; > + > + ret = sx1301_write(spi, 43, val); > + if (ret) { > + dev_err(&spi->dev, "2|43 write failed\n"); > + return ret; > + } > + > + msleep(500); > + > + ret = sx1301_read(spi, 43, &val); > + if (ret) { > + dev_err(&spi->dev, "2|43 read failed\n"); > + return ret; > + } > + > + val |= REG_2_43_RADIO_RST; > + > + ret = sx1301_write(spi, 43, val); > + if (ret) { > + dev_err(&spi->dev, "2|43 write failed\n"); > + return ret; > + } > + > + msleep(5); > + > + ret = sx1301_read(spi, 43, &val); > + if (ret) { > + dev_err(&spi->dev, "2|43 read failed\n"); > + return ret; > + } > + > + val &= ~REG_2_43_RADIO_RST; > + > + ret = sx1301_write(spi, 43, val); > + if (ret) { > + dev_err(&spi->dev, "2|43 write failed\n"); > + return ret; > + } > + > + /* radio A */ > + > + priv->radio_a_ctrl = spi_alloc_master(&spi->dev, sizeof(*radio)); > + if (!priv->radio_a_ctrl) { > + ret = -ENOMEM; > + goto err_radio_a_alloc; > + } > + > + sx1301_radio_setup(priv->radio_a_ctrl); > + priv->radio_a_ctrl->dev.of_node = of_get_child_by_name(spi- > >dev.of_node, "radio-a"); > + > + radio = spi_controller_get_devdata(priv->radio_a_ctrl); > + radio->page = 2; > + radio->regs = REG_2_SPI_RADIO_A_DATA; > + radio->parent = spi; > + > + dev_info(&spi->dev, "registering radio A SPI\n"); > + > + ret = devm_spi_register_controller(&spi->dev, priv->radio_a_ctrl); > + if (ret) { > + dev_err(&spi->dev, "radio A SPI register failed\n"); > + goto err_radio_a_register; > + } > + > + /* radio B */ > + > + priv->radio_b_ctrl = spi_alloc_master(&spi->dev, sizeof(*radio)); > + if (!priv->radio_b_ctrl) { > + ret = -ENOMEM; > + goto err_radio_b_alloc; > + } > + > + sx1301_radio_setup(priv->radio_b_ctrl); > + priv->radio_b_ctrl->dev.of_node = of_get_child_by_name(spi- > >dev.of_node, "radio-b"); > + > + radio = spi_controller_get_devdata(priv->radio_b_ctrl); > + radio->page = 2; > + radio->regs = REG_2_SPI_RADIO_B_DATA; > + radio->parent = spi; > + > + dev_info(&spi->dev, "registering radio B SPI\n"); > + > + ret = devm_spi_register_controller(&spi->dev, priv->radio_b_ctrl); > + if (ret) { > + dev_err(&spi->dev, "radio B SPI register failed\n"); > + goto err_radio_b_register; > + } > + > + dev_info(&spi->dev, "SX1301 module probed\n"); > + > + return 0; > +err_radio_b_register: > + spi_controller_put(priv->radio_b_ctrl); > +err_radio_b_alloc: > +err_radio_a_register: > + spi_controller_put(priv->radio_a_ctrl); > +err_radio_a_alloc: > + free_loradev(netdev); > +err_alloc_loradev: > +err_version: > + return ret; > +} > + > +static int sx1301_remove(struct spi_device *spi) > +{ > + struct net_device *netdev = spi_get_drvdata(spi); > + > + //unregister_loradev(netdev); > + free_loradev(netdev); > + > + dev_info(&spi->dev, "SX1301 module removed\n"); > + > + return 0; > +} > + > +#ifdef CONFIG_OF > +static const struct of_device_id sx1301_dt_ids[] = { > + { .compatible = "semtech,sx1301" }, > + {} > +}; > +MODULE_DEVICE_TABLE(of, sx1301_dt_ids); > +#endif > + > +static struct spi_driver sx1301_spi_driver = { > + .driver = { > + .name = "sx1301", > + .of_match_table = of_match_ptr(sx1301_dt_ids), > + }, > + .probe = sx1301_probe, > + .remove = sx1301_remove, > +}; > + > +module_spi_driver(sx1301_spi_driver); > + > +MODULE_DESCRIPTION("SX1301 SPI driver"); > +MODULE_AUTHOR("Andreas F?rber "); > +MODULE_LICENSE("GPL"); > -- > 2.16.4