From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id CE1B0A0543;
	Mon, 13 Jun 2022 09:29:31 +0200 (CEST)
Received: from [217.70.189.124] (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id 6BEDD40222;
	Mon, 13 Jun 2022 09:29:31 +0200 (CEST)
Received: from mga03.intel.com (mga03.intel.com [134.134.136.65])
 by mails.dpdk.org (Postfix) with ESMTP id C71BD40150;
 Mon, 13 Jun 2022 09:29:28 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple;
 d=intel.com; i=@intel.com; q=dns/txt; s=Intel;
 t=1655105369; x=1686641369;
 h=from:to:cc:subject:date:message-id:references:
 in-reply-to:content-transfer-encoding:mime-version;
 bh=11ih38NHmJSwFYS7EfSMj4tmdqzmnQfZPbpktcHelN0=;
 b=KIG5J26+Z63UGRfa6/oGB5SdOH7r5nymXxeBiXYPSGwzyMlLiPMKDPap
 CZbU6+w+vHSyaPym+YURVYRV4AVtr7V86rkDdexrH63jmpUJrzkq/qqJl
 xiJGlmXbiyG6K3rJgOxWXdzqjuJhxtGXzD9ZNwHaQIwr7b/dXgVayexCX
 HNxVD8rru9NEWqDsV6eGpnwAB/fbENFbdMYPCvwrOymNtbXb3oOLqXhAc
 zWvXnkMXI/Sml+ZlhmShIZzY/UNPJbaOfr2a8SKOZaD0Hy/WJJJXiQWfZ
 RzYPP5qUZVb6dzsMawZpYLMK2syLtwXCGzcbLGbG8qvuqAPfqecquTSmr w==;
X-IronPort-AV: E=McAfee;i="6400,9594,10376"; a="279245951"
X-IronPort-AV: E=Sophos;i="5.91,296,1647327600"; d="scan'208";a="279245951"
Received: from fmsmga002.fm.intel.com ([10.253.24.26])
 by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;
 13 Jun 2022 00:29:27 -0700
X-ExtLoop1: 1
X-IronPort-AV: E=Sophos;i="5.91,296,1647327600"; d="scan'208";a="685887497"
Received: from orsmsx602.amr.corp.intel.com ([10.22.229.15])
 by fmsmga002.fm.intel.com with ESMTP; 13 Jun 2022 00:29:26 -0700
Received: from orsmsx611.amr.corp.intel.com (10.22.229.24) by
 ORSMSX602.amr.corp.intel.com (10.22.229.15) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id
 15.1.2308.27; Mon, 13 Jun 2022 00:29:26 -0700
Received: from orsmsx610.amr.corp.intel.com (10.22.229.23) by
 ORSMSX611.amr.corp.intel.com (10.22.229.24) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id
 15.1.2308.27; Mon, 13 Jun 2022 00:29:25 -0700
Received: from orsedg603.ED.cps.intel.com (10.7.248.4) by
 orsmsx610.amr.corp.intel.com (10.22.229.23) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id
 15.1.2308.27 via Frontend Transport; Mon, 13 Jun 2022 00:29:25 -0700
Received: from NAM04-MW2-obe.outbound.protection.outlook.com (104.47.73.171)
 by edgegateway.intel.com (134.134.137.100) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.1.2308.27; Mon, 13 Jun 2022 00:29:25 -0700
ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;
 b=LUCSeNmBxKVSMqDn+EvgCSOIyAuk+omvrgZ7KzZ2WXL4bA6mOZe2hH3uWzKz8T9OIGq4DuadYw5440xCiTPV/nYtujbo3swVFtX5bY7j0SbmbfHhVkKIJnZYLlI0OiD43rzhtAQ9sClH9BzUE2GaKeUg843FnQ4+VpZnZ0mYE5wSfN2TA12cCbwtnThZNiIu+hIZhgz5VickuWaVjRPmsyGkteWyPnR8TWfqck1ON2wkVU5Sm9+bmF8aohGsxfun22yDSBPb1EbL8nEwfhi/wAqn0HOIY1tBCdFdSOj/SN/Y7NkfVaL0U0NTQCrKyrbVqFwuv/g0G2ht/6tMQlj4dQ==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; 
 s=arcselector9901;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;
 bh=HI5ffnvxtkIbxDkvOHbL6mPFYO7XKQLHE1XVpwEGx48=;
 b=i4v5ELFlq6B/qww8ylWHkC+Kmrm47TLSHvdOoKMvIM5vWqwOTv3bcA0iWNCZHXumWFcVc1YGTsev18PDRdQ/JylmVyKYXb4+aWnlGOsdG2VxtAx2iP0PDdFO9YOeiVAbKr0KlWWTtF0UXFUJCWPmOFymDSAgowwRZC/lKAMu9hcqV1XbQl4wm2QwaV5XS/4WVZVBuWTj4BtamTvMOXYPVZCtI/XULdJXlbkZ//KWYtrPjZIg2wxq9Hzjc5hazheGzqKw/GQLEeWpOiTsKD3Zc+j2dXRJDwgFIsNHH3aaQFGfSYG5IW5bbohDK2PSaT0ukHKFkpQvusKwJhL4qqsrVQ==
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass
 smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com;
 dkim=pass header.d=intel.com; arc=none
Received: from DM6PR11MB3530.namprd11.prod.outlook.com (2603:10b6:5:72::19) by
 DM4PR11MB6141.namprd11.prod.outlook.com (2603:10b6:8:b3::13) with
 Microsoft
 SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.20.5332.13; Mon, 13 Jun 2022 07:29:23 +0000
Received: from DM6PR11MB3530.namprd11.prod.outlook.com
 ([fe80::44eb:f525:1e31:d0ec]) by DM6PR11MB3530.namprd11.prod.outlook.com
 ([fe80::44eb:f525:1e31:d0ec%7]) with mapi id 15.20.5332.020; Mon, 13 Jun 2022
 07:29:23 +0000
From: "Huang, Wei" <wei.huang@intel.com>
To: "Zhang, Tianfei" <tianfei.zhang@intel.com>, "dev@dpdk.org" <dev@dpdk.org>, 
 "thomas@monjalon.net" <thomas@monjalon.net>, "nipun.gupta@nxp.com"
 <nipun.gupta@nxp.com>, "hemant.agrawal@nxp.com" <hemant.agrawal@nxp.com>
CC: "stable@dpdk.org" <stable@dpdk.org>, "Xu, Rosen" <rosen.xu@intel.com>,
 "Zhang, Qi Z" <qi.z.zhang@intel.com>
Subject: RE: [PATCH v2 1/2] raw/ifpga/base: add pmci driver
Thread-Topic: [PATCH v2 1/2] raw/ifpga/base: add pmci driver
Thread-Index: AQHYfHA/TMgXZlqCHUWmIb9hKhxaU61M7dUAgAAHtnA=
Date: Mon, 13 Jun 2022 07:29:22 +0000
Message-ID: <DM6PR11MB353083E315577E7E9AC6E9A9EFAB9@DM6PR11MB3530.namprd11.prod.outlook.com>
References: <1653443483-30971-1-git-send-email-wei.huang@intel.com>
 <1654827900-10023-1-git-send-email-wei.huang@intel.com>
 <1654827900-10023-2-git-send-email-wei.huang@intel.com>
 <BN9PR11MB5483F360E3DEC5BA33FAD554E3AB9@BN9PR11MB5483.namprd11.prod.outlook.com>
In-Reply-To: <BN9PR11MB5483F360E3DEC5BA33FAD554E3AB9@BN9PR11MB5483.namprd11.prod.outlook.com>
Accept-Language: en-US
Content-Language: en-US
X-MS-Has-Attach: 
X-MS-TNEF-Correlator: 
dlp-product: dlpe-windows
dlp-reaction: no-action
dlp-version: 11.6.500.17
authentication-results: dkim=none (message not signed)
 header.d=none;dmarc=none action=none header.from=intel.com;
x-ms-publictraffictype: Email
x-ms-office365-filtering-correlation-id: aa7e8c65-299e-4b52-b051-08da4d0e6ff1
x-ms-traffictypediagnostic: DM4PR11MB6141:EE_
x-microsoft-antispam-prvs: <DM4PR11MB6141305A8BBDBDA306BFED7BEFAB9@DM4PR11MB6141.namprd11.prod.outlook.com>
x-ms-exchange-senderadcheck: 1
x-ms-exchange-antispam-relay: 0
x-microsoft-antispam: BCL:0;
x-microsoft-antispam-message-info: kJikgYB1wY8E1BkcmLnzYrtj9pGbMDX00gBtuJUhXGTOipLExI5LGFGy9u88ZQRDZcNlCYT4oI2s3ZA7va7OWtdgoKpsWa98jzzrIMMt6mW4wqe7imRjA40QOS/e76C6d6mq67k0093RO539aUtbYVaroSQVxpcUCO0vBgRaztodEF8ctEGbqOP0nwXNd3DiminbFAh5FLiclvhVy375FOFFN4QN42IfYjlzB0qHUGsd28GJabYk9MWVHN1OOL+/suT7kN8q7OKXlYiVeH1GVrKoBA54xPSUx9hOOWypWOWPyA6wYnhNWgQk6lRba1ZBMj4UATcuwZu8RjxKUOp18L4BiahuwuiaoBBwmPGnAMuV2lXxXs0H0ZMV9Lk/63TyWD7Aapys9QkgG98nmo6JY7M1jJDz21Rt/iiVNs/Q4iy7cRYnmoH6buI08CuXfm/zl2iWTNyIo8hy54NNLQd788nxFnpFL0r6gzqQPoGEg4+TGZRGn2fN7jrxw8o/JfeTjk9WVdbyFUKB0AdqbKRLiwTTa+Kgg5Hn2k1PkB9wUidHxOlR2+UD4SXbUnTrQHWZ7l3x344+n6cjJjhSJUwWC8GYN8KtgBkPRJE8QSi1RcEArIblR6K6LuEBA24ufQDLKplMj52ztwZudlvryMMYIL4b0pggE7BNk/9tE45uTgdHAaxMAyvBy03Ko6PwMJADsY6CBwOzMJSbZc47yOArPg==
x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;
 IPV:NLI; SFV:NSPM; H:DM6PR11MB3530.namprd11.prod.outlook.com; PTR:; CAT:NONE;
 SFS:(13230016)(366004)(52536014)(508600001)(107886003)(8936002)(186003)(110136005)(54906003)(38100700002)(5660300002)(2906002)(4326008)(30864003)(66476007)(64756008)(8676002)(66446008)(66556008)(55016003)(66946007)(76116006)(83380400001)(316002)(53546011)(86362001)(6506007)(82960400001)(26005)(122000001)(33656002)(7696005)(38070700005)(9686003)(71200400001)(579004)(559001);
 DIR:OUT; SFP:1102; 
x-ms-exchange-antispam-messagedata-chunkcount: 1
x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?UIE7wuLq1jm3KYJ8T74EXoNikA0ki4bSSdFMdNPotgHCFu4uAcTbKGJOLQDK?=
 =?us-ascii?Q?C8uIqeFEU4E04cR8TRz4OFHEM3CEYeBoZ1SKoajLahypCzh3d7R2BW6ocnIV?=
 =?us-ascii?Q?v1+RehCxxC+B0RyXN7RiX6sMyQU642dxyg1H7rjTfgUigUXrJYb+ol7T0Ke7?=
 =?us-ascii?Q?SniZgp/oDFjRCaoyfrF3+gtC6jTLMJuBBquVwnFK3EsFRYJYliW+79/HGAkY?=
 =?us-ascii?Q?UJvO2EauUN4i620BG3USm4QSQlVMHRm+CoZnA+M81sVbWmyYrahrt5NvC9hy?=
 =?us-ascii?Q?72FEApJgmVMINxoMTSQbANeW5hqiY/F4A04XkIoT72zoBj8N87jIyr8/ka+f?=
 =?us-ascii?Q?/CoNXQrX3YMfFHSAOLqDFWHGuhJlmxnVZCu5pBpX9XA9TLTDBwnXPgXYTvzD?=
 =?us-ascii?Q?4S2SO8tI0WMflZsKF0WIXoWA/1V+UYjF/gI7e0baiyiqbCfYcqDR1Jz+2Td8?=
 =?us-ascii?Q?xhhHvSlebX3RHsqS5F4kbGmKAKeahgTtGSeqT0fyLhDgxrxt2lZpuiBXIRpg?=
 =?us-ascii?Q?OKEEYSyxEXBYotKUyAWQrnkGMaHQXVTilzivErmRyGAr2BUXv7rT8cplL0NL?=
 =?us-ascii?Q?OJzTXXj+CTBSLkuMna7GokNEPyDOvAelr9tQ0hDuZtlv2SCNMlGx4sgVed9Z?=
 =?us-ascii?Q?4z6XHMFd+IePO5A7n0zMaeEqOpL8HY6hsS+l+xQg9Zf42P/fh/S3guUDC0yJ?=
 =?us-ascii?Q?1a1H66KXX3H1AnEoUOU22bnuHneoFEhNNY/ACIk0hBn1bHyCeKZUu+1ItX6p?=
 =?us-ascii?Q?2UorctuVRTG04d/+WZxDjS8qLoLpAnBeoVg6CpvoLfD2pZ9354b78Rae5Roh?=
 =?us-ascii?Q?wXq8K0a44anle9LlmwWyogisI7fzht/Uyoc/UJmibJVzDp3ciOfrdNhYHctR?=
 =?us-ascii?Q?mQY7i42a/MMdlh5FZKTSbA8PBgFs5us9IUy7h7B5+3piRBS/cnbPD9kcWSw0?=
 =?us-ascii?Q?lkh4KkXX7oUKHdbaH3Yyv9klpnL5C4wxFlolY61n6k6X5myldiSHkYQh3rmC?=
 =?us-ascii?Q?VNL6/knJJHx3+yke8V87/i733yAhJ3CJP8TO9QRxpTonfXEBUjh9YTN6fMw8?=
 =?us-ascii?Q?7WHY3BQRVwhKDET49tftpDnz7LWU1CPbDD1mKULr9/1xkWjLyX9GnmxNVD5Y?=
 =?us-ascii?Q?MXa1EFjPRMvj5nWK2tVoyXEFY9pihqfjja7w7rHSPuGcf5YTxDhGBn5+CjoO?=
 =?us-ascii?Q?9jYtR4PjoiEV53uFwfO/ip8bEYXXH+yfycX0/vB3wzFUYD9S4n12Q/cqv7AG?=
 =?us-ascii?Q?sOBiNqOB5YNrzpMrSG56lsulVquVADamxf2iujipQ9/CiX6L716K5dLhyCxV?=
 =?us-ascii?Q?YYnodVVj+m0g6b9bmsMHZQVnc2QOMHGaeHr8NOvpd60iVZamYRn93ynzhNjp?=
 =?us-ascii?Q?zdWpeqO0K/W2Da871pxk6pSuGASwqQDRmrAWuNQK8WRd6Ve03gaAjtp2T9YG?=
 =?us-ascii?Q?MeFUJd1h1VsdeMfIBYS1R2ApZdYkweLABfKvUHcOYpO0SkSx64egfoKJyFLG?=
 =?us-ascii?Q?rDBeESURgGTYsbkjlsEhlVn1iRWrJK4MtCpnwHZhII+iTuZYQPjaM3Yaeh2q?=
 =?us-ascii?Q?P5J9fWFxl8cD98qXxPTMv1veVmrxvmo7yROfoc/T6YROOzNKpqaHVaPErsZC?=
 =?us-ascii?Q?WabckGjIRPmtqorOY+XtV+KMmKaA4SGC/RR8a4kAUEWgeG3W3W/lOu+Y3JtW?=
 =?us-ascii?Q?2jnM5dqaw/cjwVo7iitizZEFCIvMobDFA2agzMvkbyWSuyDbWqLVgtGm5Bho?=
 =?us-ascii?Q?KWvSJXz9Tg=3D=3D?=
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-AuthSource: DM6PR11MB3530.namprd11.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: aa7e8c65-299e-4b52-b051-08da4d0e6ff1
X-MS-Exchange-CrossTenant-originalarrivaltime: 13 Jun 2022 07:29:22.9181 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: 3izvnTn+EBCYoN79HCO9LuPWYez0/Np9pFHUfmr+SxyZ8arckiwLv+euotNkCW0CAsGinphSwoJSUnYikZi5yg==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR11MB6141
X-OriginatorOrg: intel.com
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org



> -----Original Message-----
> From: Zhang, Tianfei <tianfei.zhang@intel.com>
> Sent: Monday, June 13, 2022 15:01
> To: Huang, Wei <wei.huang@intel.com>; dev@dpdk.org;
> thomas@monjalon.net; nipun.gupta@nxp.com; hemant.agrawal@nxp.com
> Cc: stable@dpdk.org; Xu, Rosen <rosen.xu@intel.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>
> Subject: RE: [PATCH v2 1/2] raw/ifpga/base: add pmci driver
>=20
>=20
>=20
> > -----Original Message-----
> > From: Huang, Wei <wei.huang@intel.com>
> > Sent: Friday, June 10, 2022 10:25 AM
> > To: dev@dpdk.org; thomas@monjalon.net; nipun.gupta@nxp.com;
> > hemant.agrawal@nxp.com
> > Cc: stable@dpdk.org; Xu, Rosen <rosen.xu@intel.com>; Zhang, Tianfei
> > <tianfei.zhang@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; Huang,
> Wei
> > <wei.huang@intel.com>
> > Subject: [PATCH v2 1/2] raw/ifpga/base: add pmci driver
> >
> > PMCI (Platform Management Control Interface) is a new module in FPGA,
> > which is designed to cooperate with BMC chip to fulfill board managemen=
t
> > functions.
> > This driver provide interfaces to access registers of BMC chip and
> > external flash of FPGA.
> >
> > Signed-off-by: Wei Huang <wei.huang@intel.com>
> > ---
> >  drivers/raw/ifpga/base/ifpga_defines.h           | 103 ++-
> >  drivers/raw/ifpga/base/ifpga_feature_dev.c       |   2 +
> >  drivers/raw/ifpga/base/ifpga_feature_dev.h       |   1 +
> >  drivers/raw/ifpga/base/ifpga_fme.c               | 265 +++++--
> >  drivers/raw/ifpga/base/ifpga_fme_error.c         |   2 +
> >  drivers/raw/ifpga/base/ifpga_port_error.c        |   2 +-
> >  drivers/raw/ifpga/base/ifpga_sec_mgr.c           |   9 +-
> >  drivers/raw/ifpga/base/ifpga_sec_mgr.h           |   9 +-
> >  drivers/raw/ifpga/base/opae_hw_api.c             |  29 +
> >  drivers/raw/ifpga/base/opae_hw_api.h             |   1 +
> >  drivers/raw/ifpga/base/opae_intel_max10.c        | 938
> > ++++++++++++++++++++---
> >  drivers/raw/ifpga/base/opae_intel_max10.h        | 313 +++++++-
> >  drivers/raw/ifpga/base/opae_osdep.h              |  43 +-
> >  drivers/raw/ifpga/base/osdep_rte/osdep_generic.h |  10 +
> >  14 files changed, 1524 insertions(+), 203 deletions(-)
>=20
> This patch is very huge. I thinks this patch can slit into 3 patches: bas=
e PMCI
> driver, flash support and sensor support.
>=20
Agree, let me split it into three patches.
> >
> > diff --git a/drivers/raw/ifpga/base/ifpga_defines.h
> > b/drivers/raw/ifpga/base/ifpga_defines.h
> > index 9a280eb..7c8fa89 100644
> > --- a/drivers/raw/ifpga/base/ifpga_defines.h
> > +++ b/drivers/raw/ifpga/base/ifpga_defines.h
> > @@ -23,6 +23,7 @@
> >  #define FME_FEATURE_NIOS_SPI        "fme_nios_spi"
> >  #define FME_FEATURE_I2C_MASTER      "fme_i2c_master"
> >  #define FME_FEATURE_ETH_GROUP       "fme_eth_group"
> > +#define FME_FEATURE_PMCI            "fme_pmci"
> >
> >  #define PORT_FEATURE_HEADER         "port_hdr"
> >  #define PORT_FEATURE_UAFU           "port_uafu"
> > @@ -91,6 +92,7 @@ enum fpga_id_type {
> >  #define FME_FEATURE_ID_NIOS_SPI 0xd
> >  #define FME_FEATURE_ID_I2C_MASTER  0xf
> >  #define FME_FEATURE_ID_ETH_GROUP 0x10
> > +#define FME_FEATURE_ID_PMCI      0x12
> >
> >  #define PORT_FEATURE_ID_HEADER FEATURE_ID_FIU_HEADER
> >  #define PORT_FEATURE_ID_ERROR 0x10
> > @@ -266,6 +268,24 @@ struct feature_fme_bitstream_id {
> >  	union {
> >  		u64 csr;
> >  		struct {
> > +			u8 build_patch:8;
> > +			u8 build_minor:8;
> > +			u8 build_major:8;
> > +			u8 fvl_bypass:1;
> > +			u8 mac_lightweight:1;
> > +			u8 disagregate:1;
> > +			u8 lightweiht:1;
> > +			u8 seu:1;
> > +			u8 ptp:1;
> > +			u8 reserve:2;
> > +			u8 interface:4;
> > +			u32 afu_revision:12;
> > +			u8 patch:4;
> > +			u8 minor:4;
> > +			u8 major:4;
> > +			u8 reserved:4;
> > +		} v1;
> > +		struct {
> >  			u32 gitrepo_hash:32;	/* GIT repository hash */
> >  			/*
> >  			 * HSSI configuration identifier:
> > @@ -274,7 +294,8 @@ struct feature_fme_bitstream_id {
> >  			 * 2 - Ethernet
> >  			 */
> >  			u8  hssi_id:4;
> > -			u16 rsvd1:12;		/* Reserved */
> > +			u8  rsvd1:4;
> > +			u8  fim_type:8;
> >  			/* Bitstream version patch number */
> >  			u8  bs_verpatch:4;
> >  			/* Bitstream version minor number */
> > @@ -283,7 +304,7 @@ struct feature_fme_bitstream_id {
> >  			u8  bs_vermajor:4;
> >  			/* Bitstream version debug number */
> >  			u8  bs_verdebug:4;
> > -		};
> > +		} v2;
> >  	};
> >  };
> >
> > @@ -1670,31 +1691,6 @@ struct bts_header {
> >
> >  #define check_support(n) (n =3D=3D 1 ? "support" : "no")
> >
> > -/* bitstream id definition */
> > -struct fme_bitstream_id {
> > -	union {
> > -		u64 id;
> > -		struct {
> > -			u8 build_patch:8;
> > -			u8 build_minor:8;
> > -			u8 build_major:8;
> > -			u8 fvl_bypass:1;
> > -			u8 mac_lightweight:1;
> > -			u8 disagregate:1;
> > -			u8 lightweiht:1;
> > -			u8 seu:1;
> > -			u8 ptp:1;
> > -			u8 reserve:2;
> > -			u8 interface:4;
> > -			u32 afu_revision:12;
> > -			u8 patch:4;
> > -			u8 minor:4;
> > -			u8 major:4;
> > -			u8 reserved:4;
> > -		};
> > -	};
> > -};
> > -
> >  enum board_interface {
> >  	VC_8_10G =3D 0,
> >  	VC_4_25G =3D 1,
> > @@ -1703,10 +1699,30 @@ enum board_interface {
> >  	VC_2_2_25G =3D 4,
> >  };
> >
> > +enum fim_type {
> > +	BASE_ADP =3D 0,
> > +	BASE_FDK,
> > +	BASE_X16_ADP,
> > +	BASE_X16_FDK,
> > +	FIMA_10G_ADP,
> > +	FIMA_25G_ADP,
> > +	FIMA_100G_ADP,
> > +	FIMB_ADP,
> > +	FIMC_ADP
> > +};
> > +
> > +enum hssi_id {
> > +	NO_HSSI =3D 0,
> > +	PCIE_RP,
> > +	ETHER_NET
> > +};
> > +
> >  enum pac_major {
> >  	VISTA_CREEK =3D 0,
> >  	RUSH_CREEK =3D 1,
> >  	DARBY_CREEK =3D 2,
> > +	LIGHTNING_CREEK =3D 3,
> > +	ARROW_CREEK =3D 5,
> >  };
> >
> >  enum pac_minor {
> > @@ -1718,23 +1734,30 @@ enum pac_minor {
> >  struct opae_board_info {
> >  	enum pac_major major;
> >  	enum pac_minor minor;
> > -	enum board_interface type;
> > -
> > -	/* PAC features */
> > -	u8 fvl_bypass;
> > -	u8 mac_lightweight;
> > -	u8 disaggregate;
> > -	u8 lightweight;
> > -	u8 seu;
> > -	u8 ptp;
> >
> >  	u32 boot_page;
> >  	u32 max10_version;
> >  	u32 nios_fw_version;
> > -	u32 nums_of_retimer;
> > -	u32 ports_per_retimer;
> > -	u32 nums_of_fvl;
> > -	u32 ports_per_fvl;
> > +
> > +	union {
> > +		struct {  /* N3000 specific */
> > +			enum board_interface type;
> > +			u8 fvl_bypass;
> > +			u8 mac_lightweight;
> > +			u8 disaggregate;
> > +			u8 lightweight;
> > +			u8 seu;
> > +			u8 ptp;
> > +			u32 nums_of_retimer;
> > +			u32 ports_per_retimer;
> > +			u32 nums_of_fvl;
> > +			u32 ports_per_fvl;
> > +		};
> > +		struct {
> > +			enum fim_type n6000_fim_type;
> > +			enum hssi_id n6000_hssi_id;
> > +		};
> > +	};
> >  };
> >
> >  #pragma pack(pop)
> > diff --git a/drivers/raw/ifpga/base/ifpga_feature_dev.c
> > b/drivers/raw/ifpga/base/ifpga_feature_dev.c
> > index dbecc7b..0a00af1 100644
> > --- a/drivers/raw/ifpga/base/ifpga_feature_dev.c
> > +++ b/drivers/raw/ifpga/base/ifpga_feature_dev.c
> > @@ -227,6 +227,8 @@ int port_clear_error(struct ifpga_port_hw *port)
> >  	&fme_i2c_master_ops),},
> >  	{FEATURE_DRV(FME_FEATURE_ID_ETH_GROUP,
> > FME_FEATURE_ETH_GROUP,
> >  	&fme_eth_group_ops),},
> > +	{FEATURE_DRV(FME_FEATURE_ID_PMCI, FME_FEATURE_PMCI,
> > +	&fme_pmci_ops),},
> >  	{0, NULL, NULL}, /* end of arrary */
> >  };
> >
> > diff --git a/drivers/raw/ifpga/base/ifpga_feature_dev.h
> > b/drivers/raw/ifpga/base/ifpga_feature_dev.h
> > index b355d22..a637eb5 100644
> > --- a/drivers/raw/ifpga/base/ifpga_feature_dev.h
> > +++ b/drivers/raw/ifpga/base/ifpga_feature_dev.h
> > @@ -178,6 +178,7 @@ int do_pr(struct ifpga_hw *hw, u32 port_id, const
> char
> > *buffer, u32 size,
> >  extern struct ifpga_feature_ops fme_i2c_master_ops;
> >  extern struct ifpga_feature_ops fme_eth_group_ops;
> >  extern struct ifpga_feature_ops fme_nios_spi_master_ops;
> > +extern struct ifpga_feature_ops fme_pmci_ops;
> >
> >  int port_get_prop(struct ifpga_port_hw *port, struct feature_prop *pro=
p);
> >  int port_set_prop(struct ifpga_port_hw *port, struct feature_prop *pro=
p);
> > diff --git a/drivers/raw/ifpga/base/ifpga_fme.c
> > b/drivers/raw/ifpga/base/ifpga_fme.c
> > index 43c7b9c..1b9a922 100644
> > --- a/drivers/raw/ifpga/base/ifpga_fme.c
> > +++ b/drivers/raw/ifpga/base/ifpga_fme.c
> > @@ -790,19 +790,32 @@ struct ifpga_feature_ops fme_emif_ops =3D {
> >  	.uinit =3D fme_emif_uinit,
> >  };
> >
> > -static const char *board_type_to_string(u32 type)
> > -{
> > -	switch (type) {
> > -	case VC_8_10G:
> > -		return "VC_8x10G";
> > -	case VC_4_25G:
> > -		return "VC_4x25G";
> > -	case VC_2_1_25:
> > -		return "VC_2x1x25G";
> > -	case VC_4_25G_2_25G:
> > -		return "VC_4x25G+2x25G";
> > -	case VC_2_2_25G:
> > -		return "VC_2x2x25G";
> > +static const char *board_type_to_string(u32 board, u32 type)
> > +{
> > +	if (board =3D=3D VISTA_CREEK) {
> > +		switch (type) {
> > +		case VC_8_10G:
> > +			return "8x10G";
> > +		case VC_4_25G:
> > +			return "4x25G";
> > +		case VC_2_1_25:
> > +			return "2x1x25G";
> > +		case VC_4_25G_2_25G:
> > +			return "4x25G+2x25G";
> > +		case VC_2_2_25G:
> > +			return "2x2x25G";
> > +		break;
> > +		}
> > +	} else {
> > +		switch (type) {
> > +		case FIMA_10G_ADP:
> > +			return "2x4x10G";
> > +		case FIMA_25G_ADP:
> > +			return "2x2x25G";
> > +		case FIMA_100G_ADP:
> > +			return "2x100G";
> > +		break;
> > +		}
> >  	}
> >
> >  	return "unknown";
> > @@ -817,6 +830,12 @@ static const char *board_major_to_string(u32
> major)
> >  		return "RUSH_CREEK";
> >  	case DARBY_CREEK:
> >  		return "DARBY_CREEK";
> > +	case LIGHTNING_CREEK:
> > +		return "LIGHTNING_CREEK";
> > +	case ARROW_CREEK:
> > +		return "ARROW_CREEK";
> > +	default:
> > +		break;
> >  	}
> >
> >  	return "unknown";
> > @@ -859,35 +878,56 @@ static int board_type_to_info(u32 type,
> >
> >  static int fme_get_board_interface(struct ifpga_fme_hw *fme)
> >  {
> > -	struct fme_bitstream_id id;
> > +	struct feature_fme_bitstream_id id;
> >  	struct ifpga_hw *hw;
> >  	u32 val;
> > +	const char *type =3D NULL;
> > +	int ret;
> >
> >  	hw =3D fme->parent;
> >  	if (!hw)
> >  		return -ENODEV;
> >
> > -	if (fme_hdr_get_bitstream_id(fme, &id.id))
> > +	if (fme_hdr_get_bitstream_id(fme, &id.csr))
> >  		return -EINVAL;
> >
> > -	fme->board_info.major =3D id.major;
> > -	fme->board_info.minor =3D id.minor;
> > -	fme->board_info.type =3D id.interface;
> > -	fme->board_info.fvl_bypass =3D id.fvl_bypass;
> > -	fme->board_info.mac_lightweight =3D id.mac_lightweight;
> > -	fme->board_info.lightweight =3D id.lightweiht;
> > -	fme->board_info.disaggregate =3D id.disagregate;
> > -	fme->board_info.seu =3D id.seu;
> > -	fme->board_info.ptp =3D id.ptp;
> > +	if (id.v1.major =3D=3D ARROW_CREEK) {
> > +		fme->board_info.major =3D id.v2.bs_vermajor;
> > +		fme->board_info.minor =3D id.v2.bs_verminor;
> > +		fme->board_info.n6000_fim_type =3D id.v2.fim_type;
> > +		fme->board_info.n6000_hssi_id =3D id.v2.hssi_id;
> > +		type =3D board_type_to_string(fme->board_info.major,
> > +				fme->board_info.n6000_fim_type);
> > +	} else {
> > +		fme->board_info.major =3D id.v1.major;
> > +		fme->board_info.minor =3D id.v1.minor;
> > +		fme->board_info.type =3D id.v1.interface;
> > +		fme->board_info.fvl_bypass =3D id.v1.fvl_bypass;
> > +		fme->board_info.mac_lightweight =3D id.v1.mac_lightweight;
> > +		fme->board_info.lightweight =3D id.v1.lightweiht;
> > +		fme->board_info.disaggregate =3D id.v1.disagregate;
> > +		fme->board_info.seu =3D id.v1.seu;
> > +		fme->board_info.ptp =3D id.v1.ptp;
> > +		type =3D board_type_to_string(fme->board_info.major,
> > +				fme->board_info.type);
> > +	}
> >
> >  	dev_info(fme, "found: PCI dev: %02x:%02x:%x board: %s
> type: %s\n",
> >  			hw->pci_data->bus,
> >  			hw->pci_data->devid,
> >  			hw->pci_data->function,
> >  			board_major_to_string(fme->board_info.major),
> > -			board_type_to_string(fme->board_info.type));
> > +			type);
> >
> > -	dev_info(fme, "support feature:\n"
> > +	ret =3D max10_get_fpga_load_info(fme->max10_dev, &val);
> > +	if (ret)
> > +		return ret;
> > +	fme->board_info.boot_page =3D val;
> > +
> > +	if (fme->board_info.major =3D=3D VISTA_CREEK) {
> > +		dev_info(dev, "FPGA loaded from %s Image\n",
> > +			val ? "User" : "Factory");
> > +		dev_info(fme, "support feature:\n"
> >  			"fvl_bypass:%s\n"
> >  			"mac_lightweight:%s\n"
> >  			"lightweight:%s\n"
> > @@ -901,26 +941,29 @@ static int fme_get_board_interface(struct
> > ifpga_fme_hw *fme)
> >  			check_support(fme->board_info.seu),
> >  			check_support(fme->board_info.ptp));
> >
> > +		if (board_type_to_info(fme->board_info.type, &fme-
> > >board_info))
> > +			return -EINVAL;
> >
> > -	if (board_type_to_info(fme->board_info.type, &fme->board_info))
> > -		return -EINVAL;
> > -
> > -	dev_info(fme, "get board info: nums_retimers %d
> ports_per_retimer %d
> > nums_fvl %d ports_per_fvl %d\n",
> > +		dev_info(fme, "get board info: nums_retimers %d "
> > +			"ports_per_retimer %d nums_fvl %d "
> > +			"ports_per_fvl %d\n",
> >  			fme->board_info.nums_of_retimer,
> >  			fme->board_info.ports_per_retimer,
> >  			fme->board_info.nums_of_fvl,
> >  			fme->board_info.ports_per_fvl);
> > +	} else {
> > +		dev_info(dev, "FPGA loaded from %s Image\n",
> > +			val ? (val =3D=3D 1 ? "User1" : "User2") : "Factory");
> > +	}
> >
> > -	if (max10_sys_read(fme->max10_dev, FPGA_PAGE_INFO, &val))
> > -		return -EINVAL;
> > -	fme->board_info.boot_page =3D val & 0x7;
> > -
> > -	if (max10_sys_read(fme->max10_dev, MAX10_BUILD_VER, &val))
> > -		return -EINVAL;
> > +	ret =3D max10_get_bmc_version(fme->max10_dev, &val);
> > +	if (ret)
> > +		return ret;
> >  	fme->board_info.max10_version =3D val;
> >
> > -	if (max10_sys_read(fme->max10_dev, NIOS2_FW_VERSION, &val))
> > -		return -EINVAL;
> > +	ret =3D max10_get_bmcfw_version(fme->max10_dev, &val);
> > +	if (ret)
> > +		return ret;
> >  	fme->board_info.nios_fw_version =3D val;
> >
> >  	dev_info(fme, "max10 version 0x%x, nios fw version 0x%x\n",
> > @@ -983,11 +1026,25 @@ static int fme_spi_init(struct ifpga_feature
> *feature)
> >
> >  	altera_spi_init(spi_master);
> >
> > -	max10 =3D intel_max10_device_probe(spi_master, 0);
> > -	if (!max10) {
> > +	max10 =3D opae_zmalloc(sizeof(*max10));
> > +	if (!max10)
> > +		goto release_dev;
> > +
> > +	max10->spi_master =3D spi_master;
> > +	max10->type =3D M10_N3000;
> > +
> > +	max10->spi_tran_dev =3D spi_transaction_init(spi_master, 0);
> > +	if (!max10->spi_tran_dev) {
> > +		dev_err(fme, "%s spi tran init fail\n", __func__);
> > +		goto free_max10;
> > +	}
> > +
> > +	/* init the max10 device */
> > +	ret =3D intel_max10_device_init(max10);
> > +	if (ret) {
> >  		ret =3D -ENODEV;
> >  		dev_err(fme, "max10 init fail\n");
> > -		goto spi_fail;
> > +		goto release_spi_tran_dev;
> >  	}
> >
> >  	fme->max10_dev =3D max10;
> > @@ -1002,17 +1059,24 @@ static int fme_spi_init(struct ifpga_feature
> > *feature)
> >
> >  max10_fail:
> >  	intel_max10_device_remove(fme->max10_dev);
> > -spi_fail:
> > +release_spi_tran_dev:
> > +	if (max10->spi_tran_dev)
> > +		spi_transaction_remove(max10->spi_tran_dev);
> > +free_max10:
> > +	opae_free(max10);
> > +release_dev:
> >  	altera_spi_release(spi_master);
> > -	return ret;
> > +	return -ENODEV;
> >  }
> >
> >  static void fme_spi_uinit(struct ifpga_feature *feature)
> >  {
> >  	struct ifpga_fme_hw *fme =3D (struct ifpga_fme_hw *)feature-
> >parent;
> >
> > -	if (fme->max10_dev)
> > +	if (fme->max10_dev) {
> >  		intel_max10_device_remove(fme->max10_dev);
> > +		opae_free(fme->max10_dev);
> > +	}
> >  }
> >
> >  struct ifpga_feature_ops fme_spi_master_ops =3D {
> > @@ -1157,27 +1221,37 @@ static int fme_nios_spi_init(struct
> ifpga_feature
> > *feature)
> >  	/* 3. init the spi master*/
> >  	altera_spi_init(spi_master);
> >
> > +	max10 =3D opae_zmalloc(sizeof(*max10));
> > +	if (!max10)
> > +		goto release_dev;
> > +
> > +	max10->spi_master =3D spi_master;
> > +	max10->type =3D M10_N3000;
> > +
> > +	max10->spi_tran_dev =3D spi_transaction_init(spi_master, 0);
> > +	if (!max10->spi_tran_dev) {
> > +		dev_err(fme, "%s spi tran init fail\n", __func__);
> > +		goto free_max10;
> > +	}
> > +
> >  	/* init the max10 device */
> > -	max10 =3D intel_max10_device_probe(spi_master, 0);
> > -	if (!max10) {
> > +	ret =3D intel_max10_device_init(max10);
> > +	if (ret) {
> >  		ret =3D -ENODEV;
> >  		dev_err(fme, "max10 init fail\n");
> > -		goto release_dev;
> > +		goto release_spi_tran_dev;
> >  	}
> >
> >  	fme->max10_dev =3D max10;
> > -
> >  	max10->bus =3D hw->pci_data->bus;
> > -
> >  	fme_get_board_interface(fme);
> > -
> >  	mgr->sensor_list =3D &max10->opae_sensor_list;
> >
> >  	/* SPI self test */
> >  	if (spi_self_checking(max10))
> >  		goto spi_fail;
> >
> > -	ret =3D init_sec_mgr(fme);
> > +	ret =3D init_sec_mgr(fme, N3000BMC_SEC);
> >  	if (ret) {
> >  		dev_err(fme, "security manager init fail\n");
> >  		goto spi_fail;
> > @@ -1187,6 +1261,11 @@ static int fme_nios_spi_init(struct ifpga_featur=
e
> > *feature)
> >
> >  spi_fail:
> >  	intel_max10_device_remove(fme->max10_dev);
> > +release_spi_tran_dev:
> > +	if (max10->spi_tran_dev)
> > +		spi_transaction_remove(max10->spi_tran_dev);
> > +free_max10:
> > +	opae_free(max10);
> >  release_dev:
> >  	altera_spi_release(spi_master);
> >  	return -ENODEV;
> > @@ -1197,8 +1276,10 @@ static void fme_nios_spi_uinit(struct
> ifpga_feature
> > *feature)
> >  	struct ifpga_fme_hw *fme =3D (struct ifpga_fme_hw *)feature-
> >parent;
> >
> >  	release_sec_mgr(fme);
> > -	if (fme->max10_dev)
> > +	if (fme->max10_dev) {
> >  		intel_max10_device_remove(fme->max10_dev);
> > +		opae_free(fme->max10_dev);
> > +	}
> >  }
> >
> >  struct ifpga_feature_ops fme_nios_spi_master_ops =3D {
> > @@ -1230,7 +1311,7 @@ static int i2c_mac_rom_test(struct altera_i2c_dev
> > *dev)
> >  	}
> >
> >  	if (memcmp(buf, read_buf, strlen(string))) {
> > -		dev_err(NULL, "%s test fail!\n", __func__);
> > +		dev_info(NULL, "%s test fail!\n", __func__);
> >  		return -EFAULT;
> >  	}
> >
> > @@ -1499,3 +1580,81 @@ int fme_mgr_get_sensor_value(struct
> > ifpga_fme_hw *fme,
> >
> >  	return 0;
> >  }
> > +
> > +static int fme_pmci_init(struct ifpga_feature *feature)
> > +{
> > +	struct ifpga_fme_hw *fme =3D (struct ifpga_fme_hw *)feature-
> >parent;
> > +	struct intel_max10_device *max10;
> > +	struct ifpga_hw *hw;
> > +	struct opae_manager *mgr;
> > +	opae_share_data *sd =3D NULL;
> > +	int ret =3D 0;
> > +
> > +	hw =3D fme->parent;
> > +	if (!hw)
> > +		return -ENODEV;
> > +
> > +	mgr =3D hw->adapter->mgr;
> > +	if (!mgr)
> > +		return -ENODEV;
> > +
> > +	dev_info(fme, "FME PMCI Init.\n");
> > +	dev_debug(fme, "FME PMCI base addr %p.\n",
> > +			feature->addr);
> > +
> > +	max10 =3D opae_zmalloc(sizeof(*max10));
> > +	if (!max10)
> > +		return -ENOMEM;
> > +
> > +	max10->type =3D M10_N6000;
> > +	max10->mmio =3D feature->addr;
> > +	if (hw->adapter && hw->adapter->shm.ptr) {
> > +		sd =3D (opae_share_data *)hw->adapter->shm.ptr;
> > +		max10->bmc_ops.mutex =3D &sd->spi_mutex;
> > +	} else {
> > +		max10->bmc_ops.mutex =3D NULL;
> > +	}
> > +
> > +	/* init the max10 device */
> > +	ret =3D intel_max10_device_init(max10);
> > +	if (ret) {
> > +		dev_err(fme, "max10 init fail\n");
> > +		goto free_max10;
> > +	}
> > +
> > +	fme->max10_dev =3D max10;
> > +	max10->bus =3D hw->pci_data->bus;
> > +	fme_get_board_interface(fme);
> > +	mgr->sensor_list =3D &max10->opae_sensor_list;
> > +
> > +	ret =3D init_sec_mgr(fme, N6000BMC_SEC);
> > +	if (ret) {
> > +		dev_err(fme, "security manager init fail\n");
> > +		goto release_max10;
> > +	}
> > +
> > +	return ret;
> > +
> > +release_max10:
> > +	intel_max10_device_remove(max10);
> > +free_max10:
> > +	opae_free(max10);
> > +
> > +	return ret;
> > +}
> > +
> > +static void fme_pmci_uinit(struct ifpga_feature *feature)
> > +{
> > +	struct ifpga_fme_hw *fme =3D (struct ifpga_fme_hw *)feature-
> >parent;
> > +
> > +	release_sec_mgr(fme);
> > +	if (fme->max10_dev) {
> > +		intel_max10_device_remove(fme->max10_dev);
> > +		opae_free(fme->max10_dev);
> > +	}
> > +}
> > +
> > +struct ifpga_feature_ops fme_pmci_ops =3D {
> > +	.init =3D fme_pmci_init,
> > +	.uinit =3D fme_pmci_uinit,
> > +};
> > diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c
> > b/drivers/raw/ifpga/base/ifpga_fme_error.c
> > index 5905eac..c5bed28 100644
> > --- a/drivers/raw/ifpga/base/ifpga_fme_error.c
> > +++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
> > @@ -224,6 +224,8 @@ static int fme_global_error_init(struct ifpga_featu=
re
> > *feature)
> >  {
> >  	struct ifpga_fme_hw *fme =3D feature->parent;
> >
> > +	dev_info(NULL, "FME error_module Init.\n");
> > +
> >  	fme_error_enable(fme);
> >
> >  	if (feature->ctx_num)
> > diff --git a/drivers/raw/ifpga/base/ifpga_port_error.c
> > b/drivers/raw/ifpga/base/ifpga_port_error.c
> > index 189f762..6c8a7d7 100644
> > --- a/drivers/raw/ifpga/base/ifpga_port_error.c
> > +++ b/drivers/raw/ifpga/base/ifpga_port_error.c
> > @@ -88,7 +88,7 @@ static int port_error_init(struct ifpga_feature *feat=
ure)
> >  {
> >  	struct ifpga_port_hw *port =3D feature->parent;
> >
> > -	dev_info(NULL, "port error Init.\n");
> > +	dev_info(NULL, "port error_module Init.\n");
> >
> >  	spinlock_lock(&port->lock);
> >  	port_err_mask(port, false);
> > diff --git a/drivers/raw/ifpga/base/ifpga_sec_mgr.c
> > b/drivers/raw/ifpga/base/ifpga_sec_mgr.c
> > index 15fb5b6..557c4e3 100644
> > --- a/drivers/raw/ifpga/base/ifpga_sec_mgr.c
> > +++ b/drivers/raw/ifpga/base/ifpga_sec_mgr.c
> > @@ -227,7 +227,7 @@ static int n3000_bulk_write(struct
> intel_max10_device
> > *dev, uint32_t addr,
> >  	for (i =3D 0; i < n; i++) {
> >  		p =3D i << 2;
> >  		v =3D *(uint32_t *)(buf + p);
> > -		ret =3D max10_reg_write(dev, addr + p, v);
> > +		ret =3D max10_sys_raw_write(dev, addr + p, v);
> >  		if (ret < 0) {
> >  			dev_err(dev,
> >  				"Failed to write to staging area 0x%08x
> > [e:%d]\n",
> > @@ -490,7 +490,7 @@ static int n3000_reload_bmc(struct
> intel_max10_device
> > *dev, int page)
> >  			CONFIG_SEL_S(page) | REBOOT_REQ);
> >  	} else {
> >  		val =3D (page =3D=3D 0) ? 0x1 : 0x3;
> > -		ret =3D max10_reg_write(dev, IFPGA_DUAL_CFG_CTRL1, val);
> > +		ret =3D max10_sys_raw_write(dev, IFPGA_DUAL_CFG_CTRL1,
> val);
> >  		if (ret < 0) {
> >  			dev_err(dev,
> >  				"Failed to write to dual config1 register
> > [e:%d]\n",
> > @@ -498,7 +498,7 @@ static int n3000_reload_bmc(struct
> intel_max10_device
> > *dev, int page)
> >  			goto end;
> >  		}
> >
> > -		ret =3D max10_reg_write(dev, IFPGA_DUAL_CFG_CTRL0, 0x1);
> > +		ret =3D max10_sys_raw_write(dev, IFPGA_DUAL_CFG_CTRL0,
> > 0x1);
> >  		if (ret < 0) {
> >  			if (ret =3D=3D -EIO) {
> >  				ret =3D 0;
> > @@ -584,7 +584,7 @@ static uint64_t n3000_get_hw_errinfo(struct
> > ifpga_sec_mgr *smgr)
> >  	.get_hw_errinfo =3D n3000_get_hw_errinfo,
> >  };
> >
> > -int init_sec_mgr(struct ifpga_fme_hw *fme)
> > +int init_sec_mgr(struct ifpga_fme_hw *fme, enum fpga_sec_type type)
> >  {
> >  	struct ifpga_hw *hw =3D NULL;
> >  	opae_share_data *sd =3D NULL;
> > @@ -621,6 +621,7 @@ int init_sec_mgr(struct ifpga_fme_hw *fme)
> >
> >  	smgr->fme =3D fme;
> >  	smgr->max10_dev =3D fme->max10_dev;
> > +	smgr->type =3D type;
> >
> >  	return 0;
> >  }
> > diff --git a/drivers/raw/ifpga/base/ifpga_sec_mgr.h
> > b/drivers/raw/ifpga/base/ifpga_sec_mgr.h
> > index fbeba56..09cc038 100644
> > --- a/drivers/raw/ifpga/base/ifpga_sec_mgr.h
> > +++ b/drivers/raw/ifpga/base/ifpga_sec_mgr.h
> > @@ -55,6 +55,12 @@
> >  #define IFPGA_RSU_ERR_WEAROUT		-7
> >  #define IFPGA_RSU_ERR_FILE_READ		-8
> >
> > +/* Supported fpga secure manager types */
> > +enum fpga_sec_type {
> > +	N3000BMC_SEC,
> > +	N6000BMC_SEC
> > +};
> > +
> >  struct ifpga_sec_mgr;
> >
> >  struct ifpga_sec_ops {
> > @@ -80,9 +86,10 @@ struct ifpga_sec_mgr {
> >  	unsigned int *rsu_control;
> >  	unsigned int *rsu_status;
> >  	const struct ifpga_sec_ops *ops;
> > +	enum fpga_sec_type type;
> >  };
> >
> > -int init_sec_mgr(struct ifpga_fme_hw *fme);
> > +int init_sec_mgr(struct ifpga_fme_hw *fme, enum fpga_sec_type type);
> >  void release_sec_mgr(struct ifpga_fme_hw *fme);
> >  int fpga_update_flash(struct ifpga_fme_hw *fme, const char *image,
> >  	uint64_t *status);
> > diff --git a/drivers/raw/ifpga/base/opae_hw_api.c
> > b/drivers/raw/ifpga/base/opae_hw_api.c
> > index 87256fc..6b78094 100644
> > --- a/drivers/raw/ifpga/base/opae_hw_api.c
> > +++ b/drivers/raw/ifpga/base/opae_hw_api.c
> > @@ -831,6 +831,35 @@ int opae_manager_get_retimer_status(struct
> > opae_manager *mgr,
> >  }
> >
> >  /**
> > + * opae_manager_get_sensor_list - get sensor name list
> > + * @mgr: opae_manager of sensors
> > + * @buf: buffer to accommodate name list separated by semicolon
> > + * @size: size of buffer
> > + *
> > + * Return: the pointer of the opae_sensor_info
> > + */
> > +int
> > +opae_mgr_get_sensor_list(struct opae_manager *mgr, char *buf, size_t
> size)
> > +{
> > +	struct opae_sensor_info *sensor;
> > +	uint32_t offset =3D 0;
> > +
> > +	opae_mgr_for_each_sensor(mgr, sensor) {
> > +		if (sensor->name) {
> > +			if (buf && (offset < size))
> > +				snprintf(buf + offset, size - offset, "%s;",
> > +					sensor->name);
> > +			offset +=3D strlen(sensor->name) + 1;
> > +		}
> > +	}
> > +
> > +	if (buf && (offset > 0) && (offset <=3D size))
> > +		buf[offset-1] =3D 0;
> > +
> > +	return offset;
> > +}
> > +
> > +/**
> >   * opae_manager_get_sensor_by_id - get sensor device
> >   * @id: the id of the sensor
> >   *
> > diff --git a/drivers/raw/ifpga/base/opae_hw_api.h
> > b/drivers/raw/ifpga/base/opae_hw_api.h
> > index fd40e09..8aead4d 100644
> > --- a/drivers/raw/ifpga/base/opae_hw_api.h
> > +++ b/drivers/raw/ifpga/base/opae_hw_api.h
> > @@ -93,6 +93,7 @@ int opae_manager_flash(struct opae_manager *mgr,
> int
> > acc_id, const char *buf,
> >  		       u32 size, u64 *status);
> >  int opae_manager_get_eth_group_region_info(struct opae_manager
> *mgr,
> >  		u8 group_id, struct opae_eth_group_region_info *info);
> > +int opae_mgr_get_sensor_list(struct opae_manager *mgr, char *buf,
> size_t
> > size);
> >  struct opae_sensor_info *opae_mgr_get_sensor_by_name(struct
> > opae_manager *mgr,
> >  		const char *name);
> >  struct opae_sensor_info *opae_mgr_get_sensor_by_id(struct
> opae_manager
> > *mgr,
> > diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c
> > b/drivers/raw/ifpga/base/opae_intel_max10.c
> > index 9d82fb0..465494a 100644
> > --- a/drivers/raw/ifpga/base/opae_intel_max10.c
> > +++ b/drivers/raw/ifpga/base/opae_intel_max10.c
> > @@ -4,51 +4,42 @@
> >
> >  #include "opae_intel_max10.h"
> >  #include <libfdt.h>
> > +#include "opae_osdep.h"
> >
> > -int max10_reg_read(struct intel_max10_device *dev,
> > -	unsigned int reg, unsigned int *val)
> > +int max10_sys_read(struct intel_max10_device *dev,
> > +	unsigned int offset, unsigned int *val)
> >  {
> > -	if (!dev)
> > +	if (!dev || !dev->ops->reg_read)
> >  		return -ENODEV;
> >
> > -	dev_debug(dev, "%s: bus:0x%x, reg:0x%x\n", __func__, dev->bus,
> reg);
> > -
> > -	return spi_transaction_read(dev->spi_tran_dev,
> > -			reg, 4, (unsigned char *)val);
> > +	return dev->ops->reg_read(dev, dev->csr->base + offset, val);
> >  }
> >
> > -int max10_reg_write(struct intel_max10_device *dev,
> > -	unsigned int reg, unsigned int val)
> > +int max10_sys_write(struct intel_max10_device *dev,
> > +	unsigned int offset, unsigned int val)
> >  {
> > -	unsigned int tmp =3D val;
> > -
> > -	if (!dev)
> > +	if (!dev || !dev->ops->reg_write)
> >  		return -ENODEV;
> >
> > -	dev_debug(dev, "%s: bus:0x%x, reg:0x%x, val:0x%x\n", __func__,
> > -			dev->bus, reg, val);
> > -
> > -	return spi_transaction_write(dev->spi_tran_dev,
> > -			reg, 4, (unsigned char *)&tmp);
> > +	return dev->ops->reg_write(dev, dev->csr->base + offset, val);
> >  }
> >
> > -int max10_sys_read(struct intel_max10_device *dev,
> > +int max10_sys_raw_read(struct intel_max10_device *dev,
> >  	unsigned int offset, unsigned int *val)
> >  {
> > -	if (!dev)
> > +	if (!dev || !dev->ops->reg_read)
> >  		return -ENODEV;
> >
> > -
> > -	return max10_reg_read(dev, dev->base + offset, val);
> > +	return dev->ops->reg_read(dev, offset, val);
> >  }
> >
> > -int max10_sys_write(struct intel_max10_device *dev,
> > +int max10_sys_raw_write(struct intel_max10_device *dev,
> >  	unsigned int offset, unsigned int val)
> >  {
> > -	if (!dev)
> > +	if (!dev || !dev->ops->reg_write)
> >  		return -ENODEV;
> >
> > -	return max10_reg_write(dev, dev->base + offset, val);
> > +	return dev->ops->reg_write(dev, offset, val);
> >  }
> >
> >  int max10_sys_update_bits(struct intel_max10_device *dev, unsigned int
> offset,
> > @@ -67,6 +58,402 @@ int max10_sys_update_bits(struct
> intel_max10_device
> > *dev, unsigned int offset,
> >  	return max10_sys_write(dev, offset, temp);
> >  }
> >
> > +static int n3000_bulk_raw_write(struct intel_max10_device *dev,
> uint32_t
> > addr,
> > +	void *buf, uint32_t len)
> > +{
> > +	uint32_t v =3D 0;
> > +	uint32_t i =3D 0;
> > +	char *p =3D buf;
> > +	int ret =3D 0;
> > +
> > +	len =3D IFPGA_ALIGN(len, 4);
> > +
> > +	for (i =3D 0; i < len; i +=3D 4) {
> > +		v =3D *(uint32_t *)(p + i);
> > +		ret =3D max10_sys_raw_write(dev, addr + i, v);
> > +		if (ret < 0) {
> > +			dev_err(dev,
> > +				"Failed to write to staging area 0x%08x
> > [e:%d]\n",
> > +				addr + i, ret);
> > +			return ret;
> > +		}
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int n3000_bulk_raw_read(struct intel_max10_device *dev,
> > +		uint32_t addr, void *buf, uint32_t len)
> > +{
> > +	u32 v, i;
> > +	char *p =3D buf;
> > +	int ret;
> > +
> > +	len =3D IFPGA_ALIGN(len, 4);
> > +
> > +	for (i =3D 0; i < len; i +=3D 4) {
> > +		ret =3D max10_sys_raw_read(dev, addr + i, &v);
> > +		if (ret < 0) {
> > +			dev_err(dev,
> > +				"Failed to write to staging area 0x%08x
> > [e:%d]\n",
> > +				addr + i, ret);
> > +			return ret;
> > +		}
> > +		*(u32 *)(p + i) =3D v;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int n3000_flash_read(struct intel_max10_device *dev,
> > +		u32 addr, void *buf, u32 size)
> > +{
> > +	if (!dev->raw_blk_ops.read_blk)
> > +		return -ENODEV;
> > +
> > +	return dev->raw_blk_ops.read_blk(dev, addr, buf, size);
> > +}
> > +
> > +static int n3000_flash_write(struct intel_max10_device *dev,
> > +		u32 addr, void *buf, u32 size)
> > +{
> > +	if (!dev->raw_blk_ops.write_blk)
> > +		return -ENODEV;
> > +
> > +	return dev->raw_blk_ops.write_blk(dev, addr, buf, size);
> > +}
> > +
> > +static u32
> > +pmci_get_write_space(struct intel_max10_device *dev, u32 size)
> > +{
> > +	u32 count, val;
> > +	int ret;
> > +
> > +	ret =3D opae_readl_poll_timeout(dev->mmio + PMCI_FLASH_CTRL, val,
> > +				GET_FIELD(PMCI_FLASH_FIFO_SPACE, val)
> =3D=3D
> > +				PMCI_FIFO_MAX_WORDS,
> > +				PMCI_FLASH_INT_US,
> > PMCI_FLASH_TIMEOUT_US);
> > +	if (ret =3D=3D -ETIMEDOUT)
> > +		return 0;
> > +
> > +	count =3D GET_FIELD(PMCI_FLASH_FIFO_SPACE, val) * 4;
> > +
> > +	return (size > count) ? count : size;
> > +}
> > +
> > +static void pmci_write_fifo(void __iomem *base, char *buf, size_t coun=
t)
> > +{
> > +	size_t i;
> > +	u32 val;
> > +
> > +	for (i =3D 0; i < count/4 ; i++) {
> > +		val =3D *(u32 *)(buf + i * 4);
> > +		writel(val, base);
> > +	}
> > +}
> > +
> > +static void pmci_read_fifo(void __iomem *base, char *buf, size_t count=
)
> > +{
> > +	size_t i;
> > +	u32 val;
> > +
> > +	for (i =3D 0; i < count/4; i++) {
> > +		val =3D readl(base);
> > +		*(u32 *)(buf + i * 4) =3D val;
> > +	}
> > +}
> > +
> > +static int
> > +__pmci_flash_bulk_write(struct intel_max10_device *dev, u32 addr,
> > +		void *buf, u32 size)
> > +{
> > +	UNUSED(addr);
> > +	u32 blk_size, n_offset =3D 0;
> > +
> > +	while (size) {
> > +		blk_size =3D pmci_get_write_space(dev, size);
> > +		if (blk_size =3D=3D 0) {
> > +			dev_err(pmci->dev, "get FIFO available size fail\n");
> > +			return -EIO;
> > +		}
> > +		size -=3D blk_size;
> > +		pmci_write_fifo(dev->mmio + PMCI_FLASH_FIFO, (char
> *)buf +
> > n_offset,
> > +				blk_size);
> > +		n_offset +=3D blk_size;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int
> > +pmci_flash_bulk_write(struct intel_max10_device *dev, u32 addr,
> > +		void *buf, u32 size)
> > +{
> > +	int ret;
> > +
> > +	pthread_mutex_lock(dev->bmc_ops.mutex);
> > +
> > +	ret =3D __pmci_flash_bulk_write(dev, addr, buf, size);
> > +
> > +	pthread_mutex_unlock(dev->bmc_ops.mutex);
> > +	return ret;
> > +}
> > +
> > +static int
> > +pmci_set_flash_host_mux(struct intel_max10_device *dev, bool request)
> > +{
> > +	u32 ctrl;
> > +	int ret;
> > +
> > +	ret =3D max10_sys_update_bits(dev,
> > +			m10bmc_base(dev) + M10BMC_PMCI_FLASH_CTRL,
> > +			FLASH_HOST_REQUEST,
> > +			SET_FIELD(FLASH_HOST_REQUEST, request));
> > +	if (ret)
> > +		return ret;
> > +
> > +	return opae_max10_read_poll_timeout(dev, m10bmc_base(dev) +
> > M10BMC_PMCI_FLASH_CTRL,
> > +			ctrl, request ? (get_flash_mux(ctrl) =3D=3D
> > FLASH_MUX_HOST) :
> > +			(get_flash_mux(ctrl) !=3D FLASH_MUX_HOST),
> > +			PMCI_FLASH_INT_US, PMCI_FLASH_TIMEOUT_US);
> > +}
> > +
> > +static int
> > +pmci_get_mux(struct intel_max10_device *dev)
> > +{
> > +	pthread_mutex_lock(dev->bmc_ops.mutex);
> > +	return pmci_set_flash_host_mux(dev, true);
> > +}
> > +
> > +static int
> > +pmci_put_mux(struct intel_max10_device *dev)
> > +{
> > +	int ret;
> > +
> > +	ret =3D pmci_set_flash_host_mux(dev, false);
> > +	pthread_mutex_unlock(dev->bmc_ops.mutex);
> > +	return ret;
> > +}
> > +
> > +static int
> > +__pmci_flash_bulk_read(struct intel_max10_device *dev, u32 addr,
> > +		     void *buf, u32 size)
> > +{
> > +	u32 blk_size, offset =3D 0, val;
> > +	int ret;
> > +
> > +	while (size) {
> > +		blk_size =3D min_t(u32, size, PMCI_READ_BLOCK_SIZE);
> > +
> > +		opae_writel(addr + offset, dev->mmio +
> PMCI_FLASH_ADDR);
> > +
> > +		opae_writel(SET_FIELD(PMCI_FLASH_READ_COUNT,
> blk_size /
> > 4)
> > +				| PMCI_FLASH_RD_MODE,
> > +			dev->mmio + PMCI_FLASH_CTRL);
> > +
> > +		ret =3D opae_readl_poll_timeout((dev->mmio +
> > PMCI_FLASH_CTRL),
> > +				val, !(val & PMCI_FLASH_BUSY),
> > +				PMCI_FLASH_INT_US,
> > +				PMCI_FLASH_TIMEOUT_US);
> > +		if (ret) {
> > +			dev_err(dev, "%s timed out on reading flash 0x%xn",
> > +				__func__, val);
> > +			return ret;
> > +		}
> > +
> > +		pmci_read_fifo(dev->mmio + PMCI_FLASH_FIFO, (char *)buf
> +
> > offset,
> > +				blk_size);
> > +
> > +		size -=3D blk_size;
> > +		offset +=3D blk_size;
> > +
> > +		opae_writel(0, dev->mmio + PMCI_FLASH_CTRL);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int
> > +pmci_flash_bulk_read(struct intel_max10_device *dev, u32 addr,
> > +		     void *buf, u32 size)
> > +{
> > +	int ret;
> > +
> > +	ret =3D pmci_get_mux(dev);
> > +	if (ret)
> > +		return ret;
>=20
> This is a potential concurrency issue, one thread reading the flash conte=
nt
> while other thread writing the flash.
> There is a hardware lock mechanism in flash controller, when one thread
> write the flash, it got the hardware lock
> in flash controller. And at the same time, the read thread will return fa=
il on
> pmci_set_flash_host_mux(). So in this case,
> it should goto fail label to release the mutex lock.
>=20
> > +
> > +	ret =3D __pmci_flash_bulk_read(dev, addr, buf, size);
> > +	if (ret)
> > +		goto fail;
> > +
> > +	return pmci_put_mux(dev);
> > +
> > +fail:
> > +	pmci_put_mux(dev);
> > +	return ret;
> > +}
> > +
> > +static int pmci_check_flash_address(u32 start, u32 end)
> > +{
> > +	if (start < PMCI_FLASH_START || end > PMCI_FLASH_END)
> > +		return -EINVAL;
> > +
> > +	return 0;
> > +}
> > +
> > +int opae_read_flash(struct intel_max10_device *dev, u32 addr,
> > +		u32 size, void *buf)
> > +{
> > +	int ret;
> > +
> > +	if (!dev->bmc_ops.check_flash_range ||
> > +			!dev->bmc_ops.flash_read)
> > +		return -ENODEV;
> > +
> > +	if (!buf)
> > +		return -EINVAL;
> > +
> > +	ret =3D dev->bmc_ops.check_flash_range(addr, addr + size);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret =3D dev->bmc_ops.flash_read(dev, addr, buf, size);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return 0;
> > +}
> > +
> > +static int max10_spi_read(struct intel_max10_device *dev,
> > +	unsigned int addr, unsigned int *val)
> > +{
> > +	if (!dev)
> > +		return -ENODEV;
> > +
> > +	dev_debug(dev, "%s: bus:0x%x, addr:0x%x\n", __func__, dev->bus,
> > addr);
> > +
> > +	return spi_transaction_read(dev->spi_tran_dev,
> > +			addr, 4, (unsigned char *)val);
> > +}
> > +
> > +static int max10_spi_write(struct intel_max10_device *dev,
> > +	unsigned int addr, unsigned int val)
> > +{
> > +	unsigned int tmp =3D val;
> > +
> > +	if (!dev)
> > +		return -ENODEV;
> > +
> > +	dev_debug(dev, "%s: bus:0x%x, reg:0x%x, val:0x%x\n", __func__,
> > +			dev->bus, addr, val);
> > +
> > +	return spi_transaction_write(dev->spi_tran_dev,
> > +			addr, 4, (unsigned char *)&tmp);
> > +}
> > +
> > +static int indirect_bus_clr_cmd(struct intel_max10_device *dev)
> > +{
> > +	unsigned int cmd;
> > +	int ret;
> > +
> > +	opae_writel(0, dev->mmio + INDIRECT_CMD_OFF);
> > +
> > +	ret =3D opae_readl_poll_timeout((dev->mmio + INDIRECT_CMD_OFF),
> > cmd,
> > +				 (!cmd), INDIRECT_INT_US,
> > INDIRECT_TIMEOUT_US);
> > +
> > +	if (ret)
> > +		dev_err(dev, "%s timed out on clearing cmd 0x%x\n",
> > +				__func__, cmd);
> > +
> > +	return ret;
> > +}
> > +
> > +static int max10_indirect_reg_read(struct intel_max10_device *dev,
> > +	unsigned int addr, unsigned int *val)
> > +{
> > +	unsigned int cmd;
> > +	int ret;
> > +
> > +	if (!dev)
> > +		return -ENODEV;
> > +
> > +	pthread_mutex_lock(dev->bmc_ops.mutex);
> > +
> > +	cmd =3D opae_readl(dev->mmio + INDIRECT_CMD_OFF);
> > +	if (cmd)
> > +		dev_warn(dev, "%s non-zero cmd 0x%x\n", __func__, cmd);
> > +
> > +	opae_writel(addr, dev->mmio + INDIRECT_ADDR_OFF);
> > +
> > +	opae_writel(INDIRECT_CMD_RD, dev->mmio +
> INDIRECT_CMD_OFF);
> > +
> > +	ret =3D opae_readl_poll_timeout((dev->mmio + INDIRECT_CMD_OFF),
> > cmd,
> > +				 (cmd & INDIRECT_CMD_ACK),
> > INDIRECT_INT_US,
> > +				 INDIRECT_TIMEOUT_US);
> > +
> > +	*val =3D opae_readl(dev->mmio + INDIRECT_RD_OFF);
> > +
> > +	if (ret)
> > +		dev_err(dev, "%s timed out on reg 0x%x cmd 0x%x\n",
> > +				__func__, addr, cmd);
> > +
> > +	if (indirect_bus_clr_cmd(dev))
> > +		ret =3D -ETIME;
> > +
> > +	pthread_mutex_unlock(dev->bmc_ops.mutex);
> > +
> > +	return ret;
> > +}
> > +
> > +static int max10_indirect_reg_write(struct intel_max10_device *dev,
> > +	unsigned int addr, unsigned int val)
> > +{
> > +	unsigned int cmd;
> > +	int ret;
> > +
> > +	if (!dev)
> > +		return -ENODEV;
> > +
> > +	pthread_mutex_lock(dev->bmc_ops.mutex);
> > +
> > +	cmd =3D readl(dev->mmio + INDIRECT_CMD_OFF);
> > +
> > +	if (cmd)
> > +		dev_warn(dev, "%s non-zero cmd 0x%x\n", __func__, cmd);
> > +
> > +	opae_writel(val, dev->mmio + INDIRECT_WR_OFF);
> > +
> > +	opae_writel(addr, dev->mmio + INDIRECT_ADDR_OFF);
> > +
> > +	writel(INDIRECT_CMD_WR, dev->mmio + INDIRECT_CMD_OFF);
> > +
> > +	ret =3D opae_readl_poll_timeout((dev->mmio + INDIRECT_CMD_OFF),
> > cmd,
> > +				 (cmd & INDIRECT_CMD_ACK),
> > INDIRECT_INT_US,
> > +				 INDIRECT_TIMEOUT_US);
> > +
> > +	if (ret)
> > +		dev_err(dev, "%s timed out on reg 0x%x cmd 0x%x\n",
> > +				__func__, addr, cmd);
> > +
> > +	if (indirect_bus_clr_cmd(dev))
> > +		ret =3D -ETIME;
> > +
> > +	pthread_mutex_unlock(dev->bmc_ops.mutex);
> > +
> > +	return ret;
> > +}
> > +
> > +const struct m10bmc_regmap m10bmc_pmci_regmap =3D {
> > +	.reg_write =3D max10_indirect_reg_write,
> > +	.reg_read =3D max10_indirect_reg_read,
> > +};
> > +
> > +const struct m10bmc_regmap m10bmc_n3000_regmap =3D {
> > +	.reg_write =3D max10_spi_write,
> > +	.reg_read =3D max10_spi_read,
> > +};
> > +
> >  static struct max10_compatible_id max10_id_table[] =3D {
> >  	{.compatible =3D MAX10_PAC,},
> >  	{.compatible =3D MAX10_PAC_N3000,},
> > @@ -122,7 +509,7 @@ static int altera_nor_flash_read(struct
> > intel_max10_device *dev,
> >  	word_len =3D len/4;
> >
> >  	for (i =3D 0; i < word_len; i++) {
> > -		ret =3D max10_reg_read(dev, offset + i*4,
> > +		ret =3D max10_sys_raw_read(dev, offset + i*4,
> >  				&value);
> >  		if (ret)
> >  			return -EBUSY;
> > @@ -557,15 +944,13 @@ static int check_max10_version(struct
> > intel_max10_device *dev)
> >  {
> >  	unsigned int v;
> >
> > -	if (!max10_reg_read(dev, MAX10_SEC_BASE_ADDR +
> > MAX10_BUILD_VER,
> > +	if (!max10_sys_raw_read(dev, MAX10_SEC_BASE_ADDR +
> > MAX10_BUILD_VER,
> >  				&v)) {
> >  		if (v !=3D 0xffffffff) {
> >  			dev_info(dev, "secure MAX10 detected\n");
> > -			dev->base =3D MAX10_SEC_BASE_ADDR;
> >  			dev->flags |=3D MAX10_FLAGS_SECURE;
> >  		} else {
> >  			dev_info(dev, "non-secure MAX10 detected\n");
> > -			dev->base =3D MAX10_BASE_ADDR;
> >  		}
> >  		return 0;
> >  	}
> > @@ -648,73 +1033,455 @@ static int max10_staging_area_init(struct
> > intel_max10_device *dev)
> >  	return 0;
> >  }
> >
> > -struct intel_max10_device *
> > -intel_max10_device_probe(struct altera_spi_device *spi,
> > -		int chipselect)
> > +int max10_get_fpga_load_info(struct intel_max10_device *dev, unsigned
> int
> > *val)
> >  {
> > -	struct intel_max10_device *dev;
> >  	int ret;
> > -	unsigned int val;
> > +	unsigned int value;
> >
> > -	dev =3D opae_malloc(sizeof(*dev));
> > -	if (!dev)
> > -		return NULL;
> > +	/* read FPGA loading information */
> > +	ret =3D max10_sys_read(dev, dev->csr->fpga_page_info, &value);
> > +	if (ret) {
> > +		dev_err(dev, "fail to get FPGA loading info\n");
> > +		return ret;
> > +	}
> >
> > -	TAILQ_INIT(&dev->opae_sensor_list);
> > +	if (dev->type =3D=3D M10_N3000)
> > +		*val =3D value & 0x7;
> > +	else if (dev->type =3D=3D M10_N6000) {
> > +		if (!GET_FIELD(PMCI_FPGA_CONFIGED, value))
> > +			return -EINVAL;
> > +		*val =3D GET_FIELD(PMCI_FPGA_BOOT_PAGE, value);
> > +	}
> >
> > -	dev->spi_master =3D spi;
> > +	return 0;
> > +}
> >
> > -	dev->spi_tran_dev =3D spi_transaction_init(spi, chipselect);
> > -	if (!dev->spi_tran_dev) {
> > -		dev_err(dev, "%s spi tran init fail\n", __func__);
> > -		goto free_dev;
> > -	}
> > +int max10_get_bmc_version(struct intel_max10_device *dev, unsigned
> int *val)
> > +{
> > +	int ret;
> >
> > -	/* check the max10 version */
> > -	ret =3D check_max10_version(dev);
> > -	if (ret) {
> > -		dev_err(dev, "Failed to find max10 hardware!\n");
> > -		goto free_dev;
> > -	}
> > +	ret =3D max10_sys_read(dev, dev->csr->build_version, val);
> > +	if (ret)
> > +		return ret;
> >
> > -	/* load the MAX10 device table */
> > -	ret =3D init_max10_device_table(dev);
> > -	if (ret) {
> > -		dev_err(dev, "Init max10 device table fail\n");
> > -		goto free_dev;
> > -	}
> > +	return 0;
> > +}
> >
> > -	/* init max10 devices, like sensor*/
> > -	if (dev->flags & MAX10_FLAGS_SECURE)
> > -		ret =3D max10_secure_hw_init(dev);
> > -	else
> > -		ret =3D max10_non_secure_hw_init(dev);
> > -	if (ret) {
> > -		dev_err(dev, "Failed to init max10 hardware!\n");
> > -		goto free_dtb;
> > +int max10_get_bmcfw_version(struct intel_max10_device *dev,
> unsigned int
> > *val)
> > +{
> > +	int ret;
> > +
> > +	ret =3D max10_sys_read(dev, dev->csr->fw_version, val);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct m10bmc_csr m10bmc_spi_csr =3D {
> > +	.base =3D MAX10_SEC_BASE_ADDR,
> > +	.build_version =3D MAX10_BUILD_VER,
> > +	.fw_version =3D NIOS2_FW_VERSION,
> > +	.fpga_page_info =3D FPGA_PAGE_INFO,
> > +	.doorbell =3D MAX10_DOORBELL,
> > +	.auth_result =3D MAX10_AUTH_RESULT,
> > +};
> > +
> > +static const struct m10bmc_csr m10bmc_pmci_csr =3D {
> > +	.base =3D M10BMC_PMCI_SYS_BASE,
> > +	.build_version =3D M10BMC_PMCI_BUILD_VER,
> > +	.fw_version =3D NIOS2_PMCI_FW_VERSION,
> > +	.fpga_page_info =3D M10BMC_PMCI_FPGA_CONF_STS,
> > +	.doorbell =3D M10BMC_PMCI_DOORBELL,
> > +	.auth_result =3D M10BMC_PMCI_AUTH_RESULT,
> > +};
> > +
> > +static const struct max10_sensor_raw_data n6010bmc_temp_tbl[] =3D {
> > +	{ 0x444, 0x448, 0x44c, 0x0, 0x0, 500,
> > +		"FPGA E-TILE Temperature #1" },
> > +	{ 0x450, 0x454, 0x458, 0x0, 0x0, 500,
> > +		"FPGA E-TILE Temperature #2" },
> > +	{ 0x45c, 0x460, 0x464, 0x0, 0x0, 500,
> > +		"FPGA E-TILE Temperature #3" },
> > +	{ 0x468, 0x46c, 0x470, 0x0, 0x0, 500,
> > +		"FPGA E-TILE Temperature #4" },
> > +	{ 0x474, 0x478, 0x47c, 0x0, 0x0, 500,
> > +		"FPGA P-TILE Temperature" },
> > +	{ 0x484, 0x488, 0x48c, 0x0, 0x0, 500,
> > +		"FPGA FABRIC Digital Temperature#1" },
> > +	{ 0x490, 0x494, 0x498, 0x0, 0x0, 500,
> > +		"FPGA FABRIC Digital Temperature#2" },
> > +	{ 0x49c, 0x4a0, 0x4a4, 0x0, 0x0, 500,
> > +		"FPGA FABRIC Digital Temperature#3" },
> > +	{ 0x4a8, 0x4ac, 0x4b0, 0x0, 0x0, 500,
> > +		"FPGA FABRIC Digital Temperature#4" },
> > +	{ 0x4b4, 0x4b8, 0x4bc, 0x0, 0x0, 500,
> > +		"FPGA FABRIC Digital Temperature#5" },
> > +	{ 0x4c0, 0x4c4, 0x4c8, 0x0, 0x0, 500,
> > +		"FPGA FABRIC Remote Digital Temperature#1" },
> > +	{ 0x4cc, 0x4d0, 0x4d4, 0x0, 0x0, 500,
> > +		"FPGA FABRIC Remote Digital Temperature#2" },
> > +	{ 0x4d8, 0x4dc, 0x4e0, 0x0, 0x0, 500,
> > +		"FPGA FABRIC Remote Digital Temperature#3" },
> > +	{ 0x4e4, 0x4e8, 0x4ec, 0x0, 0x0, 500,
> > +		"FPGA FABRIC Remote Digital Temperature#4" },
> > +	{ 0x4f0, 0x4f4, 0x4f8, 0x0, 0x0, 500,
> > +		"Board Top Near FPGA Temperature" },
> > +	{ 0x4fc, 0x500, 0x504, 0x52c, 0x0, 500,
> > +		"Board Bottom Near CVL Temperature" },
> > +	{ 0x508, 0x50c, 0x510, 0x52c, 0x0, 500,
> > +		"Board Top East Near VRs Temperature" },
> > +	{ 0x514, 0x518, 0x51c, 0x52c, 0x0, 500,
> > +		"Columbiaville Die Temperature" },
> > +	{ 0x520, 0x524, 0x528, 0x52c, 0x0, 500,
> > +		"Board Rear Side Temperature" },
> > +	{ 0x530, 0x534, 0x538, 0x52c, 0x0, 500,
> > +		"Board Front Side Temperature" },
> > +	{ 0x53c, 0x540, 0x544, 0x0, 0x0, 500,
> > +		"QSFP1 Temperature" },
> > +	{ 0x548, 0x54c, 0x550, 0x0, 0x0, 500,
> > +		"QSFP2 Temperature" },
> > +	{ 0x554, 0x0, 0x0, 0x0, 0x0, 500,
> > +		"FPGA Core Voltage Phase 0 VR Temperature" },
> > +	{ 0x560, 0x0, 0x0, 0x0, 0x0, 500,
> > +		"FPGA Core Voltage Phase 1 VR Temperature" },
> > +	{ 0x56c, 0x0, 0x0, 0x0, 0x0, 500,
> > +		"FPGA Core Voltage Phase 2 VR Temperature" },
> > +	{ 0x578, 0x0, 0x0, 0x0, 0x0, 500,
> > +		"FPGA Core Voltage VR Controller Temperature" },
> > +	{ 0x584, 0x0, 0x0, 0x0, 0x0, 500,
> > +		"FPGA VCCH VR Temperature" },
> > +	{ 0x590, 0x0, 0x0, 0x0, 0x0, 500,
> > +		"FPGA VCC_1V2 VR Temperature" },
> > +	{ 0x59c, 0x0, 0x0, 0x0, 0x0, 500,
> > +		"FPGA VCCH, VCC_1V2 VR Controller Temperature" },
> > +	{ 0x5a8, 0x0, 0x0, 0x0, 0x0, 500,
> > +		"3V3 VR Temperature" },
> > +	{ 0x5b4, 0x5b8, 0x5bc, 0x0, 0x0, 500,
> > +		"CVL Core Voltage VR Temperature" },
> > +	{ 0x5c4, 0x5c8, 0x5cc, 0x5c0, 0x0, 500,
> > +		"FPGA P-Tile Temperature [Remote]" },
> > +	{ 0x5d0, 0x5d4, 0x5d8, 0x5c0, 0x0, 500,
> > +		"FPGA E-Tile Temperature [Remote]" },
> > +	{ 0x5dc, 0x5e0, 0x5e4, 0x5c0, 0x0, 500,
> > +		"FPGA SDM Temperature [Remote]" },
> > +	{ 0x5e8, 0x5ec, 0x5f0, 0x5c0, 0x0, 500,
> > +		"FPGA Corner Temperature [Remote]" },
> > +};
> > +
> > +static const struct max10_sensor_data n6010bmc_tmp_data =3D {
> > +	.type =3D SENSOR_TMP_NAME,
> > +	.number =3D ARRAY_SIZE(n6010bmc_temp_tbl),
> > +	.table =3D n6010bmc_temp_tbl,
> > +};
> > +
> > +static const struct max10_sensor_raw_data n6010bmc_in_tbl[] =3D {
> > +	{ 0x5f4, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"Inlet 12V PCIe Rail Voltage" },
> > +	{ 0x60c, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"Inlet 12V Aux Rail Voltage" },
> > +	{ 0x624, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"Inlet 3V3 PCIe Rail Voltage" },
> > +	{ 0x63c, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"FPGA Core Voltage Rail Voltage" },
> > +	{ 0x644, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"FPGA VCCH Rail Voltage" },
> > +	{ 0x64c, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"FPGA VCC_1V2 Rail Voltage" },
> > +	{ 0x654, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"FPGA VCCH_GXER_1V1, VCCA_1V8 Voltage" },
> > +	{ 0x664, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"FPGA VCCIO_1V2 Voltage" },
> > +	{ 0x674, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"CVL Non Core Rails Inlet Voltage" },
> > +	{ 0x684, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"MAX10 & Board CLK PWR 3V3 Inlet Voltage" },
> > +	{ 0x694, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"CVL Core Voltage Rail Voltage" },
> > +	{ 0x6ac, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"Board 3V3 VR Voltage" },
> > +	{ 0x6b4, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"QSFP 3V3 Rail Voltage" },
> > +	{ 0x6c4, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"QSFP (Primary) Supply Rail Voltage" },
> > +	{ 0x6c8, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"QSFP (Secondary) Supply Rail Voltage" },
> > +	{ 0x6cc, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"VCCCLK_GXER_2V5 Voltage" },
> > +	{ 0x6d0, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"AVDDH_1V1_CVL Voltage" },
> > +	{ 0x6d4, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"VDDH_1V8_CVL Voltage" },
> > +	{ 0x6d8, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"VCCA_PLL Voltage" },
> > +	{ 0x6e0, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"VCCRT_GXER_0V9 Voltage" },
> > +	{ 0x6e8, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"VCCRT_GXEL_0V9 Voltage" },
> > +	{ 0x6f0, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"VCCH_GXPL_1V8 Voltage" },
> > +	{ 0x6f4, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"VCCPT_1V8 Voltage" },
> > +	{ 0x6fc, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"VCC_3V3_M10 Voltage" },
> > +	{ 0x700, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"VCC_1V8_M10 Voltage" },
> > +	{ 0x704, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"VCC_1V2_EMIF1_2_3 Voltage" },
> > +	{ 0x70c, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"VCC_1V2_EMIF4_5 Voltage" },
> > +	{ 0x714, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"VCCA_1V8 Voltage" },
> > +	{ 0x718, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"VCCH_GXER_1V1 Voltage" },
> > +	{ 0x71c, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"AVDD_ETH_0V9_CVL Voltage" },
> > +	{ 0x720, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"AVDD_PCIE_0V9_CVL Voltage" },
> > +};
> > +
> > +static const struct max10_sensor_data n6010bmc_in_data =3D {
> > +	.type =3D SENSOR_IN_NAME,
> > +	.number =3D ARRAY_SIZE(n6010bmc_in_tbl),
> > +	.table =3D n6010bmc_in_tbl,
> > +};
> > +
> > +static const struct max10_sensor_raw_data n6010bmc_curr_tbl[] =3D {
> > +	{ 0x600, 0x604, 0x608, 0x0, 0x0, 1,
> > +		"Inlet 12V PCIe Rail Current" },
> > +	{ 0x618, 0x61c, 0x620, 0x0, 0x0, 1,
> > +		"Inlet 12V Aux Rail Current" },
> > +	{ 0x630, 0x634, 0x638, 0x0, 0x0, 1,
> > +		"Inlet 3V3 PCIe Rail Current" },
> > +	{ 0x640, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"FPGA Core Voltage Rail Current" },
> > +	{ 0x648, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"FPGA VCCH Rail Current" },
> > +	{ 0x650, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"FPGA VCC_1V2 Rail Current" },
> > +	{ 0x658, 0x65c, 0x660, 0x0, 0x0, 1,
> > +		"FPGA VCCH_GXER_1V1, VCCA_1V8 Current" },
> > +	{ 0x668, 0x66c, 0x670, 0x0, 0x0, 1,
> > +		"FPGA VCCIO_1V2 Current" },
> > +	{ 0x678, 0x67c, 0x680, 0x0, 0x0, 1,
> > +		"CVL Non Core Rails Inlet Current" },
> > +	{ 0x688, 0x68c, 0x680, 0x0, 0x0, 1,
> > +		"MAX10 & Board CLK PWR 3V3 Inlet Current" },
> > +	{ 0x690, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"CVL Core Voltage Rail Current" },
> > +	{ 0x6b0, 0x0, 0x0, 0x0, 0x0, 1,
> > +		"Board 3V3 VR Current" },
> > +	{ 0x6b8, 0x6bc, 0x670, 0x0, 0x0, 1,
> > +		"QSFP 3V3 Rail Current" },
> > +};
> > +
> > +static const struct max10_sensor_data n6010bmc_curr_data =3D {
> > +	.type =3D SENSOR_CURR_NAME,
> > +	.number =3D ARRAY_SIZE(n6010bmc_curr_tbl),
> > +	.table =3D n6010bmc_curr_tbl,
> > +};
> > +
> > +static const struct max10_sensor_raw_data n6010bmc_power_tbl[] =3D {
> > +	{ 0x724, 0x0, 0x0, 0x0, 0x0, 1000, "Board Power" },
> > +};
> > +
> > +static const struct max10_sensor_data n6010bmc_power_data =3D {
> > +	.type =3D SENSOR_POWER_NAME,
> > +	.number =3D ARRAY_SIZE(n6010bmc_power_tbl),
> > +	.table =3D n6010bmc_power_tbl,
> > +};
> > +
> > +static const struct max10_sensor_board_data
> n6010bmc_sensor_board_data =3D
> > {
> > +	.tables =3D {
> > +		[sensor_temp] =3D &n6010bmc_tmp_data,
> > +		[sensor_in] =3D &n6010bmc_in_data,
> > +		[sensor_curr] =3D &n6010bmc_curr_data,
> > +		[sensor_power] =3D &n6010bmc_power_data,
> > +	},
> > +};
> > +
> > +static int get_sensor_data(struct intel_max10_device *dev,
> > +		struct opae_sensor_info *sensor,
> > +		unsigned int *value,
> > +		unsigned int reg,
> > +		unsigned int flags)
> > +{
> > +	int ret;
> > +	unsigned int data;
> > +
> > +	if (!reg)
> > +		return 0;
> > +
> > +	ret =3D max10_sys_read(dev, reg, &data);
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (data =3D=3D SENSOR_INVALID) {
> > +		dev_debug(dev, "%s: sensor:%s invalid 0x%x at:%d\n",
> > +				__func__, sensor->name, data, reg);
> > +		return ret;
> >  	}
> >
> > -	/* read FPGA loading information */
> > -	ret =3D max10_sys_read(dev, FPGA_PAGE_INFO, &val);
> > -	if (ret) {
> > -		dev_err(dev, "fail to get FPGA loading info\n");
> > -		goto release_max10_hw;
> > +	*value =3D data * sensor->multiplier;
> > +	sensor->flags |=3D flags;
> > +
> > +	return 0;
> > +}
> > +
> > +static int max10_parse_sensor_data(struct intel_max10_device *dev,
> > +		const struct max10_sensor_data *sdata)
> > +{
> > +	struct opae_sensor_info *sensor;
> > +	const struct max10_sensor_raw_data *raw;
> > +	const struct max10_sensor_raw_data *table =3D
> > +		(const struct max10_sensor_raw_data *)sdata->table;
> > +	unsigned int i;
> > +	static unsigned int sensor_id;
> > +	int ret =3D 0;
> > +
> > +	for (i =3D 0; i < sdata->number; i++) {
> > +		raw =3D &table[i];
> > +
> > +		sensor =3D opae_zmalloc(sizeof(*sensor));
> > +		if (!sensor) {
> > +			ret =3D -EINVAL;
> > +			goto free_sensor;
> > +		}
> > +
> > +		sensor->type =3D sdata->type;
> > +		sensor->id =3D sensor_id++;
> > +
> > +		if (!raw->reg_input)
> > +			continue;
> > +
> > +		sensor->value_reg =3D raw->reg_input;
> > +		sensor->multiplier =3D raw->multiplier;
> > +		sensor->name =3D raw->label;
> > +
> > +		ret =3D get_sensor_data(dev, sensor,
> > +				&sensor->high_warn,
> > +				raw->reg_high_warn,
> > +				OPAE_SENSOR_HIGH_WARN_VALID);
> > +		if (ret)
> > +			break;
> > +
> > +		ret =3D get_sensor_data(dev, sensor,
> > +				&sensor->high_fatal,
> > +				raw->reg_high_fatal,
> > +				OPAE_SENSOR_HIGH_FATAL_VALID);
> > +		if (ret)
> > +			break;
> > +
> > +		ret =3D get_sensor_data(dev, sensor,
> > +				&sensor->hysteresis,
> > +				raw->reg_hyst,
> > +				OPAE_SENSOR_HYSTERESIS_VALID);
> > +		if (ret)
> > +			break;
> > +
> > +		ret =3D get_sensor_data(dev, sensor,
> > +				&sensor->low_warn,
> > +				raw->reg_low_warn,
> > +				OPAE_SENSOR_LOW_WARN_VALID);
> > +		if (ret)
> > +			break;
> > +
> > +		sensor->flags |=3D OPAE_SENSOR_VALID;
> > +
> > +		TAILQ_INSERT_TAIL(&dev->opae_sensor_list, sensor, node);
> > +		dev_info(dev, "found valid sensor: %s\n", sensor->name);
> >  	}
> > -	dev_info(dev, "FPGA loaded from %s Image\n", val ? "User" :
> "Factory");
> >
> > -	return dev;
> > +	return ret;
> >
> > -release_max10_hw:
> > +free_sensor:
> >  	max10_sensor_uinit(dev);
> > -free_dtb:
> > -	if (dev->fdt_root)
> > -		opae_free(dev->fdt_root);
> > -	if (dev->spi_tran_dev)
> > -		spi_transaction_remove(dev->spi_tran_dev);
> > -free_dev:
> > -	opae_free(dev);
> > +	return ret;
> > +}
> >
> > -	return NULL;
> > +static int max10_sensor_init_table(struct intel_max10_device *dev,
> > +		const struct max10_sensor_board_data *data)
> > +{
> > +	int ret =3D 0;
> > +	unsigned int i;
> > +	const struct max10_sensor_data *sdata;
> > +
> > +	for (i =3D 0; i < ARRAY_SIZE(data->tables); i++) {
> > +		sdata =3D data->tables[i];
> > +		if (!sdata)
> > +			continue;
> > +		ret =3D max10_parse_sensor_data(dev, sdata);
> > +		if (ret)
> > +			break;
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> > +int
> > +intel_max10_device_init(struct intel_max10_device *dev)
> > +{
> > +	int ret =3D 0;
> > +
> > +	TAILQ_INIT(&dev->opae_sensor_list);
> > +
> > +
> > +	if (dev->type =3D=3D M10_N3000) {
> > +		dev->ops =3D &m10bmc_n3000_regmap;
> > +		dev->csr =3D &m10bmc_spi_csr;
> > +
> > +		dev->raw_blk_ops.write_blk =3D n3000_bulk_raw_write;
> > +		dev->raw_blk_ops.read_blk =3D n3000_bulk_raw_read;
> > +		dev->bmc_ops.flash_read =3D n3000_flash_read;
> > +		dev->bmc_ops.flash_write =3D n3000_flash_write;
> > +
> > +		/* check the max10 version */
> > +		ret =3D check_max10_version(dev);
> > +		if (ret) {
> > +			dev_err(dev, "Failed to find max10 hardware!\n");
> > +			return ret;
> > +		}
> > +
> > +		/* load the MAX10 device table */
> > +		ret =3D init_max10_device_table(dev);
> > +		if (ret) {
> > +			dev_err(dev, "Init max10 device table fail\n");
> > +			return ret;
> > +		}
> > +
> > +		/* init max10 devices, like sensor*/
> > +		if (dev->flags & MAX10_FLAGS_SECURE)
> > +			ret =3D max10_secure_hw_init(dev);
> > +		else
> > +			ret =3D max10_non_secure_hw_init(dev);
> > +		if (ret) {
> > +			dev_err(dev, "Failed to init max10 hardware!\n");
> > +			opae_free(dev->fdt_root);
> > +			return ret;
> > +		}
> > +	} else if (dev->type =3D=3D M10_N6000) {
> > +		dev->ops =3D &m10bmc_pmci_regmap;
> > +		dev->csr =3D &m10bmc_pmci_csr;
> > +		dev->staging_area_size =3D MAX_STAGING_AREA_SIZE;
> > +		dev->flags |=3D MAX10_FLAGS_SECURE;
> > +
> > +		dev->bmc_ops.flash_read =3D pmci_flash_bulk_read;
> > +		dev->bmc_ops.flash_write =3D pmci_flash_bulk_write;
> > +		dev->bmc_ops.check_flash_range =3D
> pmci_check_flash_address;
> > +
> > +		ret =3D max10_sensor_init_table(dev,
> > &n6010bmc_sensor_board_data);
> > +		if (ret)
> > +			return ret;
> > +
> > +		ret =3D pthread_mutex_init(&dev->bmc_ops.lock, NULL);
> > +		if (ret)
> > +			return ret;
> > +
> > +		if (!dev->bmc_ops.mutex)
> > +			dev->bmc_ops.mutex =3D &dev->bmc_ops.lock;
> > +	}
> > +
> > +	return ret;
> >  }
> >
> >  int intel_max10_device_remove(struct intel_max10_device *dev)
> > @@ -722,15 +1489,14 @@ int intel_max10_device_remove(struct
> > intel_max10_device *dev)
> >  	if (!dev)
> >  		return 0;
> >
> > -	max10_sensor_uinit(dev);
> > +	pthread_mutex_destroy(&dev->bmc_ops.lock);
> >
> > -	if (dev->spi_tran_dev)
> > -		spi_transaction_remove(dev->spi_tran_dev);
> > +	if (dev->type =3D=3D M10_N3000) {
> > +		max10_sensor_uinit(dev);
> >
> > -	if (dev->fdt_root)
> > -		opae_free(dev->fdt_root);
> > -
> > -	opae_free(dev);
> > +		if (dev->fdt_root)
> > +			opae_free(dev->fdt_root);
> > +	}
> >
> >  	return 0;
> >  }
> > diff --git a/drivers/raw/ifpga/base/opae_intel_max10.h
> > b/drivers/raw/ifpga/base/opae_intel_max10.h
> > index e761d7e..ead48ea 100644
> > --- a/drivers/raw/ifpga/base/opae_intel_max10.h
> > +++ b/drivers/raw/ifpga/base/opae_intel_max10.h
> > @@ -7,6 +7,9 @@
> >
> >  #include "opae_osdep.h"
> >  #include "opae_spi.h"
> > +#include "ifpga_compat.h"
> > +
> > +struct intel_max10_device;
> >
> >  struct max10_compatible_id {
> >  	char compatible[128];
> > @@ -29,6 +32,64 @@ struct max10_compatible_id {
> >  /** List of opae sensors */
> >  TAILQ_HEAD(opae_sensor_list, opae_sensor_info);
> >
> > +/* Supported MAX10 BMC types */
> > +enum m10bmc_type {
> > +	M10_N3000,
> > +	M10_N6000
> > +};
> > +
> > +struct regmap_range {
> > +	unsigned int min;
> > +	unsigned int max;
> > +};
> > +
> > +struct m10bmc_regmap {
> > +	int (*reg_write)(struct intel_max10_device *dev,
> > +			unsigned int reg, unsigned int val);
> > +	int (*reg_read)(struct intel_max10_device *dev,
> > +			unsigned int reg, unsigned int *val);
> > +	const struct regmap_range *range;
> > +	int num_ranges;
> > +};
> > +
> > +struct m10bmc_csr {
> > +	unsigned int base;
> > +	unsigned int build_version;
> > +	unsigned int fw_version;
> > +	unsigned int fpga_page_info;
> > +	unsigned int doorbell;
> > +	unsigned int auth_result;
> > +};
> > +
> > +/**
> > + * struct flash_raw_blk_ops - device specific operations for flash R/W
> > + * @write_blk: write a block of data to flash
> > + * @read_blk: read a block of data from flash
> > + */
> > +struct flash_raw_blk_ops {
> > +	int (*write_blk)(struct intel_max10_device *dev, uint32_t addr,
> > +			void *buf, uint32_t size);
> > +	int (*read_blk)(struct intel_max10_device *dev, uint32_t addr,
> > +			void *buf, uint32_t size);
> > +};
> > +
> > +/**
> > + * struct m10bmc_ops - device specific operations
> > + * @lock: prevent concurrent flash read/write
> > + * @mutex: prevent concurrent bmc read/write
> > + * @flash_read: read a block of data from flash
> > + * @flash_write: write a block of data to flash
> > + */
> > +struct m10bmc_ops {
> > +	pthread_mutex_t lock;
> > +	pthread_mutex_t *mutex;
> > +	int (*check_flash_range)(u32 start, u32 end);
> > +	int (*flash_read)(struct intel_max10_device *dev, u32 addr,
> > +			void *buf, u32 size);
> > +	int (*flash_write)(struct intel_max10_device *dev, u32 addr,
> > +			void *buf, u32 size);
> > +};
> > +
> >  struct intel_max10_device {
> >  	unsigned int flags; /*max10 hardware capability*/
> >  	struct altera_spi_device *spi_master;
> > @@ -40,6 +101,12 @@ struct intel_max10_device {
> >  	struct opae_sensor_list opae_sensor_list;
> >  	u32 staging_area_base;
> >  	u32 staging_area_size;
> > +	enum m10bmc_type type;
> > +	const struct m10bmc_regmap *ops;
> > +	const struct m10bmc_csr *csr;
> > +	struct flash_raw_blk_ops raw_blk_ops;
> > +	struct m10bmc_ops bmc_ops;
> > +	u8 *mmio; /* mmio address for PMCI */
> >  };
> >
> >  /* retimer speed */
> > @@ -87,6 +154,7 @@ struct opae_retimer_status {
> >  /* System Registers */
> >  #define MAX10_BASE_ADDR		0x300400
> >  #define MAX10_SEC_BASE_ADDR	0x300800
> > +
> >  /* Register offset of system registers */
> >  #define NIOS2_FW_VERSION	0x0
> >  #define MAX10_MACADDR1		0x10
> > @@ -151,6 +219,32 @@ struct opae_retimer_status {
> >  #define   SEC_STATUS_NON_INC		0x6
> >  #define   SEC_STATUS_ERASE_FAIL		0x7
> >  #define   SEC_STATUS_WEAROUT		0x8
> > +#define   SEC_STATUS_PMCI_SS_FAIL           0x9
> > +#define   SEC_STATUS_FLASH_CMD              0xa
> > +#define   SEC_STATUS_FACTORY_UNVERITY       0xb
> > +#define   SEC_STATUS_FACTORY_ACTIVE         0xc
> > +#define   SEC_STATUS_POWER_DOWN             0xd
> > +#define   SEC_STATUS_CANCELLATION           0xe
> > +#define   SEC_STATUS_HASH                   0xf
> > +#define   SEC_STATUS_FLASH_ACCESS           0x10
> > +#define   SEC_STATUS_SDM_PR_CERT            0x20
> > +#define   SEC_STATUS_SDM_PR_NIOS_BUSY       0x21
> > +#define   SEC_STATUS_SDM_PR_TIMEOUT         0x22
> > +#define   SEC_STATUS_SDM_PR_FAILED          0x23
> > +#define   SEC_STATUS_SDM_PR_MISMATCH        0x24
> > +#define   SEC_STATUS_SDM_PR_FLUSH           0x25
> > +#define   SEC_STATUS_SDM_SR_CERT            0x30
> > +#define   SEC_STATUS_SDM_SR_NIOS_BUSY       0x31
> > +#define   SEC_STATUS_SDM_SR_TIMEOUT         0x32
> > +#define   SEC_STATUS_SDM_SR_FAILED          0x33
> > +#define   SEC_STATUS_SDM_SR_MISMATCH        0x34
> > +#define   SEC_STATUS_SDM_SR_FLUSH           0x35
> > +#define   SEC_STATUS_SDM_KEY_CERT           0x40
> > +#define   SEC_STATUS_SDM_KEY_NIOS_BUSY      0x41
> > +#define   SEC_STATUS_SDM_KEY_TIMEOUT        0x42
> > +#define   SEC_STATUS_SDM_KEY_FAILED         0x43
> > +#define   SEC_STATUS_SDM_KEY_MISMATCH       0x44
> > +#define   SEC_STATUS_SDM_KEY_FLUSH          0x45
> >  #define   SEC_STATUS_NIOS_OK		0x80
> >  #define   SEC_STATUS_USER_OK		0x81
> >  #define   SEC_STATUS_FACTORY_OK		0x82
> > @@ -158,9 +252,65 @@ struct opae_retimer_status {
> >  #define   SEC_STATUS_FACTORY_FAIL	0x84
> >  #define   SEC_STATUS_NIOS_FLASH_ERR	0x85
> >  #define   SEC_STATUS_FPGA_FLASH_ERR	0x86
> > +#define   SEC_STATUS_MAX   SEC_STATUS_FPGA_FLASH_ERR
> > +
> > +/* Authentication status */
> > +#define SEC_AUTH_G(v)	((v) & 0xff)
> > +#define AUTH_STAT_PASS    0x0
> > +#define AUTH_STAT_B0_MAGIC   0x1
> > +#define AUTH_STAT_CONLEN  0x2
> > +#define AUTH_STAT_CONTYPE 0x3
> > +#define AUTH_STAT_B1_MAGIC 0x4
> > +#define AUTH_STAT_ROOT_MAGIC 0x5
> > +#define AUTH_STAT_CURVE_MAGIC 0x6
> > +#define AUTH_STAT_PERMISSION 0x7
> > +#define AUTH_STAT_KEY_ID    0x8
> > +#define AUTH_STAT_CSK_MAGIC 0x9
> > +#define AUTH_STAT_CSK_CURVE 0xa
> > +#define AUTH_STAT_CSK_PERMISSION 0xb
> > +#define AUTH_STAT_CSK_ID    0xc
> > +#define AUTH_STAT_CSK_SM 0xd
> > +#define AUTH_STAT_B0_E_MAGIC 0xe
> > +#define AUTH_STAT_B0_E_SIGN 0xf
> > +#define AUTH_STAT_RK_P      0x10
> > +#define AUTH_STAT_RE_SHA    0x11
> > +#define AUTH_STAT_CSK_SHA   0x12
> > +#define AUTH_STAT_B0_SHA    0x13
> > +#define AUTH_STAT_KEY_INV   0x14
> > +#define AUTH_STAT_KEY_CAN   0x15
> > +#define AUTH_STAT_UP_SHA    0x16
> > +#define AUTH_STAT_CAN_SHA   0x17
> > +#define AUTH_STAT_HASH      0x18
> > +#define AUTH_STAT_INV_ID    0x19
> > +#define AUTH_STAT_KEY_PROG  0x1a
> > +#define AUTH_STAT_INV_BC    0x1b
> > +#define AUTH_STAT_INV_SLOT  0x1c
> > +#define AUTH_STAT_IN_OP     0x1d
> > +#define AUTH_STAT_TIME_OUT  0X1e
> > +#define AUTH_STAT_SHA_TO    0x1f
> > +#define AUTH_STAT_CSK_TO    0x20
> > +#define AUTH_STAT_B0_TO     0x21
> > +#define AUTH_STAT_UP_TO     0x22
> > +#define AUTH_STAT_CAN_TO    0x23
> > +#define AUTH_STAT_HASH_TO   0x24
> > +#define AUTH_STAT_AUTH_IDLE 0xfe
> > +#define AUTH_STAT_GA_FAIL   0xff
> > +#define AUTH_STAT_S_ERR     0x8000
> > +#define AUTH_STAT_S_MN      0x8001
> > +#define AUTH_STAT_SH_CRC     0x8002
> > +#define AUTH_STAT_SD_CRC    0x8003
> > +#define AUTH_STAT_SD_LEN    0x8004
> > +#define AUTH_STAT_S_ID      0x8005
> > +#define AUTH_STAT_S_THR    0x8006
> > +#define AUTH_STAT_S_TO      0x8007
> > +#define AUTH_STAT_S_EN     0x8008
> > +#define AUTH_STAT_SF       0x8009
> > +#define AUTH_STAT_MAX    AUTH_STAT_SF
> > +
> >  #define   CONFIG_SEL		BIT(28)
> >  #define   CONFIG_SEL_S(v)	(((v) & 0x1) << 28)
> >  #define   REBOOT_REQ		BIT(29)
> > +#define   REBOOT_DISABLED	BIT(30)
> >  #define MAX10_AUTH_RESULT	0x404
> >
> >  /* PKVL related registers, in system register region */
> > @@ -185,22 +335,26 @@ struct opae_retimer_status {
> >  #define MAX_STAGING_AREA_BASE	0xffffffff
> >  #define MAX_STAGING_AREA_SIZE	0x3800000
> >
> > -int max10_reg_read(struct intel_max10_device *dev,
> > -	unsigned int reg, unsigned int *val);
> > -int max10_reg_write(struct intel_max10_device *dev,
> > -	unsigned int reg, unsigned int val);
> > +#define m10bmc_base(max10) ((max10)->csr->base)
> > +#define doorbell_reg(max10) ((max10)->csr->doorbell)
> > +#define auth_result_reg(max10) ((max10)->csr->auth_result)
> > +
> >  int max10_sys_read(struct intel_max10_device *dev,
> >  	unsigned int offset, unsigned int *val);
> >  int max10_sys_write(struct intel_max10_device *dev,
> >  	unsigned int offset, unsigned int val);
> > +int max10_sys_raw_read(struct intel_max10_device *dev,
> > +	unsigned int offset, unsigned int *val);
> > +int max10_sys_raw_write(struct intel_max10_device *dev,
> > +	unsigned int offset, unsigned int val);
> >  int max10_sys_update_bits(struct intel_max10_device *dev,
> >  	unsigned int offset, unsigned int msk, unsigned int val);
> > -struct intel_max10_device *
> > -intel_max10_device_probe(struct altera_spi_device *spi,
> > -		int chipselect);
> > +int max10_get_bmcfw_version(struct intel_max10_device *dev,
> unsigned int
> > *val);
> > +int max10_get_bmc_version(struct intel_max10_device *dev, unsigned
> int
> > *val);
> > +int max10_get_fpga_load_info(struct intel_max10_device *dev, unsigned
> int
> > *val);
> > +int intel_max10_device_init(struct intel_max10_device *dev);
> >  int intel_max10_device_remove(struct intel_max10_device *dev);
> >
> > -
> >  #define SENSOR_REG_VALUE 0x0
> >  #define SENSOR_REG_HIGH_WARN 0x1
> >  #define SENSOR_REG_HIGH_FATAL 0x2
> > @@ -254,4 +408,147 @@ struct opae_sensor_info {
> >  	unsigned int value_reg;
> >  };
> >
> > +#define SENSOR_INVALID 0xdeadbeef
> > +
> > +struct max10_sensor_raw_data {
> > +	unsigned int reg_input;
> > +	unsigned int reg_high_warn;
> > +	unsigned int reg_high_fatal;
> > +	unsigned int reg_hyst;
> > +	unsigned int reg_low_warn;
> > +	unsigned int multiplier;
> > +	const char *label;
> > +};
> > +
> > +struct max10_sensor_data {
> > +	const char *type;
> > +	unsigned int number;
> > +	const struct max10_sensor_raw_data *table;
> > +};
> > +
> > +enum max10_sensor_types {
> > +	sensor_temp,
> > +	sensor_in,
> > +	sensor_curr,
> > +	sensor_power,
> > +	sensor_max,
> > +};
> > +
> > +#define SENSOR_TMP_NAME "Temperature"
> > +#define SENSOR_IN_NAME "Voltage"
> > +#define SENSOR_CURR_NAME "Current"
> > +#define SENSOR_POWER_NAME "Power"
> > +
> > +struct max10_sensor_board_data {
> > +	const struct max10_sensor_data *tables[sensor_max];
> > +};
> > +
> > +/* indirect access for PMCI */
> > +#define PMCI_INDIRECT_BASE 0x400
> > +#define INDIRECT_CMD_OFF   (PMCI_INDIRECT_BASE + 0x0)
> > +#define INDIRECT_CMD_RD	BIT(0)
> > +#define INDIRECT_CMD_WR	BIT(1)
> > +#define INDIRECT_CMD_ACK	BIT(2)
> > +
> > +#define INDIRECT_ADDR_OFF	 (PMCI_INDIRECT_BASE + 0x4)
> > +#define INDIRECT_RD_OFF	         (PMCI_INDIRECT_BASE + 0x8)
> > +#define INDIRECT_WR_OFF	 (PMCI_INDIRECT_BASE + 0xc)
> > +
> > +#define INDIRECT_INT_US	1
> > +#define INDIRECT_TIMEOUT_US	10000
> > +
> > +#define M10BMC_PMCI_SYS_BASE 0x0
> > +#define M10BMC_PMCI_SYS_END  0xfff
> > +
> > +#define M10BMC_PMCI_BUILD_VER   0x0
> > +#define NIOS2_PMCI_FW_VERSION   0x4
> > +
> > +#define M10BMC_PMCI_PWR_STATE 0xb4
> > +#define PMCI_PRIMARY_IMAGE_PAGE GENMASK(10, 8)
> > +
> > +#define M10BMC_PMCI_DOORBELL 0x1c0
> > +#define PMCI_DRBL_REBOOT_DISABLED BIT(1)
> > +#define M10BMC_PMCI_AUTH_RESULT 0x1c4
> > +
> > +#define M10BMC_PMCI_MAX10_RECONF 0xfc
> > +#define PMCI_MAX10_REBOOT_REQ BIT(0)
> > +#define PMCI_MAX10_REBOOT_PAGE BIT(1)
> > +
> > +#define M10BMC_PMCI_FPGA_RECONF 0xb8
> > +#define PMCI_FPGA_RECONF_PAGE  GENMASK(22, 20)
> > +#define PMCI_FPGA_RP_LOAD      BIT(23)
> > +
> > +#define PMCI_FLASH_CTRL 0x40
> > +#define PMCI_FLASH_WR_MODE BIT(0)
> > +#define PMCI_FLASH_RD_MODE BIT(1)
> > +#define PMCI_FLASH_BUSY    BIT(2)
> > +#define PMCI_FLASH_FIFO_SPACE GENMASK(13, 4)
> > +#define PMCI_FLASH_READ_COUNT GENMASK(25, 16)
> > +
> > +#define PMCI_FLASH_INT_US       1
> > +#define PMCI_FLASH_TIMEOUT_US   10000
> > +
> > +#define PMCI_FLASH_ADDR 0x44
> > +#define PMCI_FLASH_FIFO 0x800
> > +#define PMCI_READ_BLOCK_SIZE 0x800
> > +#define PMCI_FIFO_MAX_BYTES 0x800
> > +#define PMCI_FIFO_MAX_WORDS (PMCI_FIFO_MAX_BYTES / 4)
> > +
> > +#define M10BMC_PMCI_FPGA_POC	0xb0
> > +#define PMCI_FPGA_POC		BIT(0)
> > +#define PMCI_NIOS_REQ_CLEAR	BIT(1)
> > +#define PMCI_NIOS_STATUS	GENMASK(5, 4)
> > +#define NIOS_STATUS_IDLE	0
> > +#define NIOS_STATUS_SUCCESS	1
> > +#define NIOS_STATUS_FAIL	2
> > +#define PMCI_USER_IMAGE_PAGE	GENMASK(10, 8)
> > +#define POC_USER_IMAGE_1	1
> > +#define POC_USER_IMAGE_2	2
> > +#define PMCI_FACTORY_IMAGE_SEL	BIT(31)
> > +
> > +#define M10BMC_PMCI_FPGA_CONF_STS 0xa0
> > +#define PMCI_FPGA_BOOT_PAGE  GENMASK(2, 0)
> > +#define PMCI_FPGA_CONFIGED   BIT(3)
> > +
> > +#define M10BMC_PMCI_FLASH_CTRL 0x1d0
> > +#define FLASH_MUX_SELECTION GENMASK(2, 0)
> > +#define FLASH_MUX_IDLE 0
> > +#define FLASH_MUX_NIOS 1
> > +#define FLASH_MUX_HOST 2
> > +#define FLASH_MUX_PFL  4
> > +#define get_flash_mux(mux)  GET_FIELD(FLASH_MUX_SELECTION, mux)
> > +#define FLASH_NIOS_REQUEST BIT(4)
> > +#define FLASH_HOST_REQUEST BIT(5)
> > +
> > +#define M10BMC_PMCI_SDM_CTRL_STS 0x230
> > +#define PMCI_SDM_IMG_REQ	BIT(0)
> > +#define PMCI_SDM_STAT GENMASK(23, 16)
> > +
> > +#define SDM_STAT_DONE    0x0
> > +#define SDM_STAT_PROV    0x1
> > +#define SDM_STAT_BUSY    0x2
> > +#define SDM_STAT_INV     0x3
> > +#define SDM_STAT_FAIL    0x4
> > +#define SDM_STAT_BMC_BUSY 0x5
> > +#define SDM_STAT_TO      0x6
> > +#define SDM_STAT_DB      0x7
> > +#define SDM_STAT_CON_R    0x8
> > +#define SDM_STAT_CON_E    0x9
> > +#define SDM_STAT_WAIT     0xa
> > +#define SDM_STAT_RTO      0xb
> > +#define SDM_STAT_SB       0xc
> > +#define SDM_STAT_RE       0xd
> > +#define SDM_STAT_PDD     0xe
> > +#define SDM_STAT_ISC     0xf
> > +#define SDM_STAT_SIC     0x10
> > +#define SDM_STAT_NO_PROV  0x11
> > +#define SDM_STAT_CS_MIS   0x12
> > +#define SDM_STAT_PR_MIS   0x13
> > +#define SDM_STAT_MAX SDM_STAT_PR_MIS
> > +
> > +#define PMCI_FLASH_START 0x10000
> > +#define PMCI_FLASH_END 0xC7FFFFF
> > +
> > +int opae_read_flash(struct intel_max10_device *dev, u32 addr,
> > +		u32 size, void *buf);
> >  #endif
> > diff --git a/drivers/raw/ifpga/base/opae_osdep.h
> > b/drivers/raw/ifpga/base/opae_osdep.h
> > index 18e6a11..033b7e0 100644
> > --- a/drivers/raw/ifpga/base/opae_osdep.h
> > +++ b/drivers/raw/ifpga/base/opae_osdep.h
> > @@ -79,15 +79,38 @@ struct uuid {
> >  #define time_before(a, b)	time_after(b, a)
> >  #define opae_memset(a, b, c)    memset((a), (b), (c))
> >
> > -#define opae_readq_poll_timeout(addr, val, cond, invl, timeout)\
> > -({									     \
> > -	int wait =3D 0;							     \
> > -	for (; wait <=3D timeout; wait +=3D invl) {			     \
> > -		(val) =3D opae_readq(addr);				     \
> > -		if (cond)                  \
> > -			break;						     \
> > -		udelay(invl);						     \
> > -	}								     \
> > -	(cond) ? 0 : -ETIMEDOUT;	  \
> > +#define readx_poll_timeout(op, val, cond, invl, timeout, args...) \
> > +({                                                                \
> > +	unsigned long __wait =3D 0;                                     \
> > +	unsigned long __invl =3D (invl);                                \
> > +	unsigned long __timeout =3D (timeout);                          \
> > +	for (; __wait <=3D __timeout; __wait +=3D __invl) {               \
> > +		(val) =3D op(args);                                         \
> > +		if (cond)                                                 \
> > +			break;                                                \
> > +		udelay(__invl);                                           \
> > +	}                                                             \
> > +	(cond) ? 0 : -ETIMEDOUT;                                      \
> >  })
> > +
> > +#define opae_readq_poll_timeout(addr, val, cond, invl, timeout) \
> > +	readx_poll_timeout(opae_readq, val, cond, invl, timeout, addr)
> > +
> > +#define opae_readl_poll_timeout(addr, val, cond, invl, timeout) \
> > +	readx_poll_timeout(opae_readl, val, cond, invl, timeout, addr)
> > +
> > +#define opae_readw_poll_timeout(addr, val, cond, invl, timeout) \
> > +	readx_poll_timeout(opae_readw, val, cond, invl, timeout, addr)
> > +
> > +#define opae_readb_poll_timeout(addr, val, cond, invl, timeout) \
> > +	readx_poll_timeout(opae_readb, val, cond, invl, timeout, addr)
> > +
> > +#define opae_max10_read_poll_timeout(dev, addr, value, cond, invl,
> timeout)
> > \
> > +({ \
> > +	int __ret, __tmp; \
> > +	__tmp =3D readx_poll_timeout(max10_sys_read, __ret, __ret ||
> (cond), \
> > +			invl, timeout, (dev), (addr), &(value)); \
> > +	__ret?:__tmp; \
> > +})
> > +
> >  #endif
> > diff --git a/drivers/raw/ifpga/base/osdep_rte/osdep_generic.h
> > b/drivers/raw/ifpga/base/osdep_rte/osdep_generic.h
> > index 3ff49a8..68499e6 100644
> > --- a/drivers/raw/ifpga/base/osdep_rte/osdep_generic.h
> > +++ b/drivers/raw/ifpga/base/osdep_rte/osdep_generic.h
> > @@ -39,6 +39,16 @@
> >  #define min(a, b) RTE_MIN(a, b)
> >  #define max(a, b) RTE_MAX(a, b)
> >
> > +#define min_t(type, x, y) ({                    \
> > +	type __min1 =3D (x);                      \
> > +	type __min2 =3D (y);                      \
> > +	__min1 < __min2 ? __min1 : __min2; })
> > +
> > +#define max_t(type, x, y) ({                    \
> > +	type __max1 =3D (x);                      \
> > +	type __max2 =3D (y);                      \
> > +	__max1 > __max2 ? __max1 : __max2; })
> > +
> >  #define spinlock_t rte_spinlock_t
> >  #define spinlock_init(x) rte_spinlock_init(x)
> >  #define spinlock_lock(x) rte_spinlock_lock(x)
> > --
> > 1.8.3.1