Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754248AbcKATa7 (ORCPT ); Tue, 1 Nov 2016 15:30:59 -0400 Received: from mail-bl2nam02on0061.outbound.protection.outlook.com ([104.47.38.61]:29798 "EHLO NAM02-BL2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754200AbcKATa4 (ORCPT ); Tue, 1 Nov 2016 15:30:56 -0400 Authentication-Results: spf=fail (sender IP is 66.35.236.227) smtp.mailfrom=opensource.altera.com; ettus.com; dkim=pass (signature was verified) header.d=altera.onmicrosoft.com;ettus.com; dmarc=none action=none header.from=opensource.altera.com; Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=atull@opensource.altera.com; From: Alan Tull To: Greg Kroah-Hartman CC: Rob Herring , , "Moritz Fischer" , Dinh Nguyen , , Alan Tull Subject: [[PATCH repost v21] 08/11] fpga: fpga-region: device tree control for FPGA Date: Tue, 1 Nov 2016 14:14:29 -0500 Message-ID: <1478027672-4857-9-git-send-email-atull@opensource.altera.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1478027672-4857-1-git-send-email-atull@opensource.altera.com> References: <1478027672-4857-1-git-send-email-atull@opensource.altera.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [67.164.136.211] X-ClientProxiedBy: CO2PR06CA030.namprd06.prod.outlook.com (10.141.242.30) To CY1PR03MB1519.namprd03.prod.outlook.com (10.163.17.25) X-MS-Office365-Filtering-Correlation-Id: 51cc8eb7-3385-4b7f-1947-08d4028b6b28 X-Microsoft-Exchange-Diagnostics-untrusted: 1;CY1PR03MB1519;2:oq2RaUcuqj2mXCbG+yYTp41iv7lO1nIU7tPbBfjdhU2xf6tuaIWfKcXLAGIVI9St2u27oLa6numvBj5mYN/Ce2eioUDmXv6miIKKp6g5SL1sETMAAaHkdrFCvHLsaAAHEqBrZLB3ejMRsdsTl3PTfxMhcK+M/AyvCEs8RMmKa2xTBtEPvIdcc+9xK5GeL5t0C+H/k2TnJkx+7pMb0ei36g==;3:kgfoSza4Hv46FpoGXuMv9vQVJBCkVynKXrOYf+5nydlp2dSub5xlVunoWWIP/lJtG0kEPoHTaxMWMGp7YBGZxTp7cFREWElO5Sc9RDc0Tnd3Ks6e+jdsZawgWEyNDQJWw3SLjECbZyp/ubGam4LzHg==;25:pQF9pKFSZtX/X+hTO8wTqNyZuXkCJK+Hnoq9XIlFvikLbQAs85t7V5wZ5yIHpTvca3miiZZnSn3HtX7DxAygaQ6wtlpkRQUPAsX6atSEbWV5zDyxoaoLIG10aLgi/B+KjThEtWun2VIbdxzYarvrxSHKfRBnugGSb3zxB1HUBcGUYZGZgmeSnrZ9WTXETh22bA4bz2Y09TA7Ubosw2lWJFWVTNIfewd3rScj58ji0fZOqnA0Z4b6wUGPVgnfp/U9hVWi7Kt6gsudqrVhyo3QKErnIRbDvLXW+8oCiUurQgi3gte7bUnBBvE57RP+Fyhy17JRo5zTtyVmbgZnV5f+V8io3wR4PvG7Sq7bF13z75s2da1WbPXdNsI+JdhSI9PVjCuzZV/hsam5FeR2SEEjPomMo/akMurE77GwdUwlu2s+hWWfbqfffZhW4/BBmk30Pu60AHXc8CMPnQDPDbbXpw== X-Microsoft-Antispam-Untrusted: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:CY1PR03MB1519; X-Microsoft-Exchange-Diagnostics-untrusted: 1;CY1PR03MB1519;31:ry5UmTZhaT16yRvQdBWaJV8coXNUAS0C8YUpEnkGSh5Hc2gpWoETYbCzlhtFKAnDQpfX5ZKAFZ7UxK9qR7WgvpGl7773cK5x6WiaiMtmJUnF6ewlnBmijiFhGB0qRNOr8Dc5lYElooe2QJCDXArVx+PC7JeCUQ84c4Cgg0AxMJmS8/My8mH0XTORLqaAHimMKMMsqD6rYeanJB4yXNsk3vMLK04Qgwr/8nCPSC8lMOrsmSkeTVIvXyz9EBcvND6Q/Y7stgbz1n2eJ4WNCW4XJQ==;20:jNpl2qI0bXTybuErmkiSsThC36DcvqTfbU6yCGEp1JKy9YNdxYS70pVy4CaQIZuvLMQHbNNkv2DgHY3EUPMYtNrAodVrbdoYhI8MvdPTdoK6M+sB/0bgCMcQUdCJq45p0WJnFM3aPyBSE0q0XUTs3fVp+FYNcv0jhL6GP3opXvU= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(250305191791016)(22074186197030)(80048183373757);UriScan:(250305191791016)(22074186197030)(80048183373757); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040176)(6045074)(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001)(6055026)(6046074)(6072074);SRVR:CY1PR03MB1519;BCL:0;PCL:0;RULEID:;SRVR:CY1PR03MB1519;BCL:0;PCL:0;RULEID:(6040176)(6045074)(601004)(2401047)(5005006)(8121501046)(13017025)(13023025)(13018025)(13015025)(13024025)(3002001)(10201501046)(6055026)(6046074)(6072074);SRVR:BY2PR03MB286;BCL:0;PCL:0;RULEID:;SRVR:BY2PR03MB286; X-Microsoft-Exchange-Diagnostics-untrusted: 1;CY1PR03MB1519;4:OZLQn8TYFqelyEEN076dF+aTzOOT6+jR2Ww9XUI56KtbclB6Tr+qhNJ/D2LHwYy5Dvq2DUgZXt4G53ozTKtCcL5wiFZoG50ofCQ7JhLKK4YDXkIGXGCmNgOVSixosD1goy6asdQ/TzjmuxUC76CQnKqL+Y48K4ovevCDbImga/XDc7w+Dx+JrfwtArUUdCvFNu180U2xEL8LA8NV2IeEHhDSaxRbr9rPs2Ne/sGQcQxSVAbDy+93iE9zD9vVC9VQMNmrqL36oh2n1Jiivq48r1I+kMnZc1fk93PEJkSWBjuImE5Ir8Au0gfYGGp/RP8EhUPKyoDyIXYXj3tCQhspV8ze3vPaRiBVMXpUQzOmnMzINz58UPvR1wfCPwYggfWeqxZAxvHPek0p3DWfOQqQwrBdIL8knkekbLEp0Bz4kZC93bWsyX6u5Xo77A7oITBIuWvDBH8hnfWQQUxg5E5o3O5gEf7HjK/zgJCDI8Iwj/omJe+c9iL02JVeLp8l77Oe2IjxtaaWQEvfpwoYzeV/pSDywEcPaoD3Z1nLVxalCIwuK++Cr1+b+cOCLKkePrLOgqr4i14jvH6dOlxlNZFLEg== X-Forefront-PRVS: 01136D2D90 X-Forefront-Antispam-Report-Untrusted: SFV:NSPM;SFS:(10009020)(4630300001)(6009001)(7916002)(189002)(199003)(92566002)(3846002)(77096005)(7846002)(19580395003)(19580405001)(6666003)(68736007)(81156014)(81166006)(4001430100002)(101416001)(86362001)(8676002)(5660300001)(76176999)(6116002)(305945005)(50986999)(2906002)(7736002)(575784001)(33646002)(110136003)(66066001)(42882006)(42186005)(105586002)(47776003)(107886002)(5003940100001)(2950100002)(586003)(6916009)(229853001)(4326007)(15975445007)(48376002)(106356001)(50466002)(189998001)(50226002)(97736004)(2004002);DIR:OUT;SFP:1101;SCL:1;SRVR:CY1PR03MB1519;H:atull-VirtualBox.hsd1.nm.comcast.net;FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:0;LANG:en; X-Microsoft-Exchange-Diagnostics-untrusted: =?us-ascii?Q?1;CY1PR03MB1519;23:e2y3fRKxyxkIQfd4nJDm6d9+7hhB4sjp/uIUdrPGz?= =?us-ascii?Q?W7DKv5+md4kMwbX234fLQDUngoOyCzFBlvLkilwu+3GU3b2qzWRCt1qTWILE?= =?us-ascii?Q?aknA7ZNLbKc8v9/q3YNcmyzfwaZHDhgvuTp37tyiOVJcrco9vAb094/dxor9?= =?us-ascii?Q?4aCiQzpIvE7LpbOq/neB6DYQwWUpvcYed475bGhdzc42C99IXk1M7prdie9j?= =?us-ascii?Q?xcx4jTdntgnH/vpBzqND4qz5iujVEiB1ZXMsTo3WAM5lnfi1ZR2ve/EkJxd5?= =?us-ascii?Q?o79b7nm+dG/hhXnLQyNU+FNHGgTekWXg+O4bZiNP0ABG8AarckvNbFr6z3Ph?= =?us-ascii?Q?GTwhLjoaVNInlKmFrZXHlo9UGGck1Rts2M00YlEQ/XZZHGOdGrbaBbg8Piab?= =?us-ascii?Q?1cLxvrocWPSVRSn9YQfsDkweSGwLijrLk4Rwns9B41X6IuQxdfWGotGlc+nH?= =?us-ascii?Q?wi7CkcnSka2wLD09puqBFhaSSeCbOKQZyiRkxDftxdcbCB8SIN+1RYX9w9Au?= =?us-ascii?Q?Wrh7NzoKb3n4t0GezGxFrHyetcJUOu1k3yXemg2i4qGvnbEW6uv5gGgKUt6e?= =?us-ascii?Q?54qHHG9AvUQ4ZcrA+rCx7zH+pR5QC31RAwW2XXBBfB/5ypN6DGYNAkx0+O25?= =?us-ascii?Q?UCcS3o6UCNhTYWAPH+EpaHeQA9XLZKtVVwkm/Jn+7Q8npNmmaASEzkOTUok3?= =?us-ascii?Q?XQXoWkW6A0IUUJqLTYkGPHo7pebvaaeTOskzsxCq4EITVt82QXcDQo7zDxzX?= =?us-ascii?Q?Zw40S2EPiY7z/puY4yfZosbuEQFj8vNzrAv6J6np4iPfjzgepUbeOb4fAVvd?= =?us-ascii?Q?2UHCCg7218YP+ZGbd68rbbe13WktzdkKVKtEUWtveyeRTQPQ23JZAOM7paXZ?= =?us-ascii?Q?zagQQ7WcstQQz3wQSqjPiTf1KzGe9baEaQ38oh4jskMnlP43iuYYceyhqgiM?= =?us-ascii?Q?3UYUt2Cfjv55dwf2ctP2S96e8n+dUI+5SPedoC3mPThftjmoak1JjdKtP/Jc?= =?us-ascii?Q?Un16ic+7FBPS97C9ProJ4jH7OJMbkMLO62Uu1lhQWmnhDbn6gztaQ8aU+uvp?= =?us-ascii?Q?UiYDwcFS4YFU8LFiYKl9sE6kXkEpwaL8++iSLCgh/cxOblATjqhw7xV7aDUn?= =?us-ascii?Q?va6XXTwj1RC4jH/8HFBXGo63LnVug0s4LERmgBZgcBm37eC9107/Tovuzny7?= =?us-ascii?Q?G2PYJ9XCm0UPXaJHguJ+SmtzuVZhVV4EWjx?= X-Microsoft-Exchange-Diagnostics-untrusted: 1;CY1PR03MB1519;6:PFSYNLg2B95i3cYQAKL+GLZz3e1PQd9E4kQAA8wDJWqILHRRZ8T3UwOCRBHQLhYjfBsLBg161JzDJ1EhhMhQ/Yw618Rxa7VfQya4+/ssEei2iSFRxX6liDuoxlpsRt9VaCrPSPI5GrlX4/dwth1l5SY08QHTH+aykPHgbPB6eeWCELLMIykybmBJZkP4yV6yS01EMUFkSbmxgn+8RCWIDAGy9AzYhA7cpbBqeImuNfCp/JSw7PbtbOOP0jfyC1oDzRrlTfTDOIU4Y/cYj+hphRsadOQfLaDFICeBpJK4YrymgB6iXWSPUAFxi8Eg3IC3dgX/ENBOUqzeLVZx9PKFjU/qukCUKPw+j5eVLItCxNwjAgBVVkkHFtMeZwQNEZp1;5:9cAbocCvWCFgsfieL4Htqj3nS/Xwon+npoFRGjz1bVjk/Z8YxDsV3Zva2MbraP2STuKiGoeI/Thkq3VXSGq3o/v3XNreBdldVpHxR05oppyQW9Cn5GvdTCf3+N9aTdEnBLA+t7L5RUgFtsBF4ZeSRw==;24:g7OlR7pT0XX+nefaWlbtuJ0eBe0uI+BicrI5URcwKL5ems3fkDO82kT4SaXpPjq4NZt/sSqGYtlPbi8xUpVPWAS0DSJ616wNlV5iZVo7U34= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics-untrusted: 1;CY1PR03MB1519;7:C7q1mXkNetw+1xQYlt4wy1k7+ft/31x7O6z3zxH0HVhK3q6T64nSFu/dBcbwaq2WtK8IA6GzoEZHtyBLH0i8LpUZHNvgNgVfqpptES2d+iVD4Y2bNZxaXlXkT5relniDuoVKdZqFXlmlDHSpi37UtqjL9oI/AlELzJ8DzWVABCjlsw1HHm7Lr6Cc2IVdd2j8U7MSNcnnqZsP/IgcZAuqX3ul+2xdCMeP+HFAm/xIPhh3vMtJYtR5KZDLYNPsGZ1yK95xUm7WEJhUdSxbkrEWowNgLYBrnSXymfqkDdgnq4/DNwJSxU73XHFike/1rjvn91maiIz++XbEmJ/9DSQFdi+w4MBfKQrknzkiMNF3vs0= X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY1PR03MB1519 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-HT: Tenant X-Forefront-Antispam-Report: CIP:66.35.236.227;IPV:NLI;CTRY:US;EFV:NLI;SFV:NSPM;SFS:(10009020)(6009001)(7916002)(2980300002)(1109001)(1110001)(339900001)(189002)(199003)(47776003)(4326007)(8936002)(11100500001)(87936001)(85426001)(107886002)(6070500001)(575784001)(6666003)(86362001)(2950100002)(42882006)(189998001)(6916009)(97736004)(19580395003)(19580405001)(33646002)(77096005)(76176999)(3720700001)(50986999)(105606002)(229853001)(106466001)(15975445007)(7846002)(626004)(66066001)(305945005)(336002)(92566002)(5660300001)(110136003)(6116002)(5003940100001)(48376002)(50466002)(50226002)(81166006)(356003)(2906002)(68736007)(81156014)(7736002)(586003)(4001430100002)(8676002)(956001)(3846002)(7099028)(2004002);DIR:OUT;SFP:1101;SCL:1;SRVR:BY2PR03MB286;H:sj-itexedge03.altera.priv.altera.com;FPR:;SPF:Fail;PTR:InfoDomainNonexistent;MX:1;A:0;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;BY2FFO11OLC008;1:qn5ilLiG9rua60bT6jZoEPUwKtvCAcU1ne/tJJslmdQ0O2K1c/nJUs1qgwowgGmFHKha/ESurNsRNFdBKh+yYOCWOLsa1wYKhw6UDNPEkjmirz3QAXIivLog0m8/FYJsKMxRoNtXeOjxEUsLf1ByM1b1qjaz4uGrGpzrE/uS2q3Mr+5uYQ8CePXes5BOVZpv2IZiI0LM3WdggmvMAop7Tln6oQKi6ruPICdiIPuTIkLTlQu8JUOe+w+xW4eXOxMBZ8b5LzxervUCXVMD1n9otGEsacvgQOx2Pd0WSaXlgiES72pCXCevI/WKwbzH2jUjKuVioI9jf8j5OklGZoGBR+0Pq69tFI36knl3QeOxonNVvLcE3TqbC/nK+iSizJSdnOKIJy/ygEvPjl2CWPb23USrPtNuVRlDhb4F7WZHtITPyuFRR70wcXAqWsxFH1zGl2zxreEdBU3q0fRjyzA5ua8lydr6nPPrW+0dtHET4fhnLYVLoQ9uOB3mm+fT+bVnyEzEuDPjxydvQojFWQVZiN4+hxbLAcXGDndOXxL6l55oIZlI/C9EC4pbS1yyiiQ15JDrlYhfRwnRYT+EkGc07Q== X-MS-Exchange-Transport-CrossTenantHeadersStripped: BY2FFO11OLC008.protection.gbl X-Microsoft-Exchange-Diagnostics: 1;BY2PR03MB286;2:bN2XKQw5IakRgBdnup5y8LBSHukQo2HBCV5xMHsWngy3lrr6inJYKTYozac+dhUmDsYqKZ/45XAzK28zgvsWiOA00BG6dY5ElPXExyioE3vMP5CVlrSv19GYXx/e3dYn0l4mCAAX2pnh64T4gx2n3cKC4iR2zFkACtSI+is9847Y/KOPvc8AdWlzUzHXZaY+IgtmCugKH2HdOFWMgKf0lA==;3:rngfBt/PWCOL5YKxhDYrbzBGJrwNe5ChbUd4Qi1EnNj+V00goqhoN5d2OEewCbu6BkCXL/Y9ZizoQUaiqDZHqDgqjChr8bikA1V+3XPmtNkVi8SIkqQUvcPPkO8SIhp51GyZy4Fn/JwOOwOFMqG68Fc0efN3/DdDwzogkIx5h75LW2aapxkDOfTZtlvM/zDDtvP3YAFyttl2+a74hUhjH/GyHdwAnqnuDqfAmj3b7owHSaUnHbNxd7OllZizh7lSDqjGeCAxd7utSUlxEohw/A== X-DkimResult-Test: Passed X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(3001016);SRVR:BY2PR03MB286; X-Microsoft-Exchange-Diagnostics: 1;BY2PR03MB286;25:5XCc7XRInxsh39CF0QrkgbELdsjgvcV5fs6DoL+lzMaVqWKLG0Ey5ohzaWgatqWXXBLhiGgzbrO1NJnyShDu3czcN+fbtuZE9lObki014D/29lyxj1yPf32W6fFaDxwPbAxOZhIAfXHA7ZCG9qKx8Dp3wa5erj5fBUWCIX/VHa9c78FeNXQk4Hh3k88hbOhV7v+3buVqRKHKXW7MEApd5mC1tPVG2C93a7ZybSxs9u4GoFm7WuL5layai7IYuaeEINGs7hYuV68HkwTsEfg8jrVNJ3ysgG/xY8hm8sDKI8Cc5Q8TEGrtWr2djU7ODjDEmJ9Iag9kXt8HDHYNV2vxG7DXLEPLnOXovC1Yk04XXAmGCUjqxVkadZdZWv1txAF+ld4F97PLVfFWOEWV4Y5aVMa4C1J3lVMVJiDphmGuWaMKjX2n+/TBxYAuiq0xtD4LfQSfK4VofANj8qPJ+Q36NHdKiE5Gefp5++wzEIwlPzXoJumRT3uJO5hcMlvxilnVMloQcI74ZbbQWT+Go1saqDz18NB78T4Swuo8DyfRFixvr6FCKP79OVC6vhYcGZn7xueYE4KAesUtzD1DT9OZRKrPr4YhuVcUS2kRL2Z9AXN5BGNvl/mfm1zwAjvYC36mdrFaUjMmS0nnb6K8euoQ61DPx6GoP5mMswDXalO9WQwsJbKhvwP0Zh679JlUTQS2ItI/Otog7B4YQQBsAuNlJBViSqJq6Y9zCRQqJHkNZLwBflgVt5I8LnAgi/uV3/VefMnoMtykjalCalJIt5u3QaqPryC97ehQ7Xxg/xxajUsKetEq3UU24Lw3kC1qzbm6W0DnHDj/yCZHkNyRUg7nrHlLgKCT1lSlIQdZzdiCJulN3sogMMTdA9CGa6IXh3ta3ERLXGBIgLnlrVHSX8dQLCKV+DXjPTC7aN2BylOT2mM= X-Microsoft-Exchange-Diagnostics: 1;BY2PR03MB286;31:p2Ft5Yrh/HqJkVFK6YrOd+W5Jlinjk5vLCHgfyb9B7miVOH2FEONxxf2Q2WdAxEIfUfVHUT0Z/WCGoArcxiNHYpWq7wpoTeZFh8+8Q6hzje3MITvp5rFKAqSfVaFPKjAMOyFW+mRBcP9smvo4ew8tQaFZfDcdAo7EMu3gocfhQN/3oG4/MywMG5j4LBID0K8nd79i+GxGWwXXdE+mCQ7ZzoaDnQ4brhsvHhOHo50OeDtO2J7dz03p+AeTgsrYQ4ZgP1Vengz7/Dd7sd93YfgwivenAz6lreTwkUX8F+q1ts=;20:Cjscv1p/qVMVKPm06hyKEOTZUoyqJSPzBRz0zenbtHABx2rKaV2a1faLhTuQ/hyO7QbymkxFThQj9hjE2uaBF/JjkzKOHlM5pV8BHtsYNPkctKjy9kHP+ikayebMtQ9WUcWkgoGN+Mpv2tvgr672nTNqY5MM1UwefgrH0aqeJQU= X-Microsoft-Exchange-Diagnostics: 1;BY2PR03MB286;4:/+YUzirhXzgUbWAQbyVulyh1HkkVwt5LM8rEEL6H3+bW76/mVsUE43OXMNaNwwyfi/Vkjb2w8Uqy5PaFbtHNyZ+OfJ/KKx3PAEPU15Rj+TnhlLmLGXdsZdx0m+2rhimB2/LgLVlLMqj3lT2ezC+0FfaAyCwTlLr7G+PPtZLNoAKLx0FoSkF/j2Bc82k+d2oSvO9tmyvfUxhok525C9UxE0A/HPav8keJ/pbzT6mjSS32q8qRuDUdPFWUCyj1DpQgVfkdRKSMvzgoQ9mTWRkXbRPdRgWIGmf1R4NrrcWeMgNBulfcHyIjpTxGnHcW17DvII6Uvh05Q4q11bj4UGnH6hQ0ylPHAuAbyhh9CrfITKOp9AuASlJwhpjxKFSVl6j4laYfIpW5C3HhddZkeWloY3UNtbZqgl0TGgoIj91rCud9SpZUueVZ5N/N9BnUwu262IZVVnpwZjeU7p3aF1RCDPxOcKBmC1ZzHYrzu+sSdbJ0lFvkNx8qAuUaKtyUEPelJzfDETv2r1AsQgaTj1AJOS2fEIm11YQ221lEXggAKe1J498fzp7oOXo8BzmICfAave83W5J3Btkzy7+DJ8ZZz33ouTCplGSBBdYxZiOTj3/nZMEGXqccccYXRNaoRQPHu4tBd/LdCwjxRB0OxRGinVVT5k7bhHgtDtPCRC4vHVMcvOOESevig+0PWXtG/pe0 X-Forefront-PRVS: 01136D2D90 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BY2PR03MB286;23:ZvtmWTIuVYksd3UrFzkbHVvc02uyR6bP6Sdk+M2zvo?= =?us-ascii?Q?OMWNAgcYj+vEQMsbfhqz6f2YWvHTsgyAJrk9KBDnbqqXpbZKld61MrC4F2sp?= =?us-ascii?Q?w3yXpoe7QIEM1ht+m23XK8x8wDMb1148F+7j0xrOAwHAgVeQXyjROouHpNBS?= =?us-ascii?Q?PyokSZQk93atNOHtc636tVqG8jLcbs/RzQjCHrjqEpkfirWCzKINy1pMSRJe?= =?us-ascii?Q?mwlud/W95fAHJPxcJNQRMQqK14m8077bpxHu+PNrMoMZVJK6WWif5429cykG?= =?us-ascii?Q?8UFo+ea55IqBWdT36htMM0Be89kUQqlF1BpsIudqnKUhwn66tQTtVQj+dMVU?= =?us-ascii?Q?npmXEXyMvLLCM0PlmjJrEPn4Q5Vit8bHJvUq5mgzFrg1FtacIa+uM+z9dFBT?= =?us-ascii?Q?TqUjOpyXYp8GDbLUgo1TV2IcTfCO1WGlZyYFJ39CwdNe4dtYXY13X7wU4cSD?= =?us-ascii?Q?7bGRL9+nCme0RrHsxH3UEio9t0EqPDc649FbQs4PepUf9reNd0WhhGxOOhwe?= =?us-ascii?Q?GjTyGJts4hTMISPYLWX/1G51QJs/fURNUVuyOvZOYaG4rYVEgy5ozRZgHRk4?= =?us-ascii?Q?TrfMmiFJZ9t9zqDWdk/8NQXoePvG/D9hjNuF+1Hq4DJJxeeJslQ/k3MOXvqh?= =?us-ascii?Q?QoPEIi8sUJ4URDEAkGy8aI7gaNkBTnazGnF+D8O2l+2nt3xo8pi6Vo2ZruGa?= =?us-ascii?Q?q+DVGnH+TrTukYy3Or5QAVxnb7yK23Zx0z/MtukYBxowLKw2HWK6kPKxrxMV?= =?us-ascii?Q?oCAGODDCIfWmR73Gpfc/hIvE/lid8sPpvSbgdwOtCDUXF4J4tDR9CxYMZCAd?= =?us-ascii?Q?vAobSEv+45adfdu0c1B5M04UnNUwKOy+OdXHWCoFVrDub1Eko1yQLvIDntCe?= =?us-ascii?Q?Wlo42v3CnxZ3gYVqmC3Cq7SON8cJDfgG/Stkc68A3T22R5cQFspujlLvbZWf?= =?us-ascii?Q?Z4CMfyqYRw25kaptC/tLeCwy+ki9ADs4z1HcaRpz+mjIy8SkOKDT3b6EHFjW?= =?us-ascii?Q?m6vZQxwuFpIVwTndGLPrXPKDB8j2jj32XNW7+T+RWWm2yg3rWB+MQ30y/o+C?= =?us-ascii?Q?K4KBqHfwib8L9yAqKLGOMZ6MrvbSqwd2rvvNlQXrmrs5z5qyxVFpD6dp8CX4?= =?us-ascii?Q?V1K0CZEi/bWwVWzSXT/eEZX/g30Jqgsf9KTYvwmo9MDDIznrrRHCBEnyRKT1?= =?us-ascii?Q?NtnDBZWVxPbT1oJDNB/nHcKHj49SSsvLv4nYBorcXhcG6Ew+LmvbJvRqvkWP?= =?us-ascii?Q?5woEMnFHIOqru16jbUj6Km5xtyY0jvO/sXWZT3lOKurcHsoFR4kn1EVUGmoz?= =?us-ascii?Q?iVOIJ5UYHTkR/veqDM33fvqaL0JazhtUFtN1BxWzKhY3er/86qz7EMEKf5Ao?= =?us-ascii?Q?80MFsiXDThAs7qescQOqqQ88Bks6jutCGzIqBGEaWH30Qeffgb34zwxkrQoV?= =?us-ascii?Q?DIToBI70ZUcfpYElJvlUyDmqnwQ9o=3D?= X-Microsoft-Exchange-Diagnostics: 1;BY2PR03MB286;6:mbse23hGQBGzdMP1z+TuSmZe05OxkQpeqWB4w0qShC9zKk6UArXsvV5Hr09r5CDZeT5tl6WOZygoaXuJoRlJxJG0NWy8wXJ7zf6PZwrdC6/6s9fk+eFCtRv/KpMujD5JZM0BMTrti8yXwn3rXIEleMLX1cO630vP5druJeTSSLk2yul0fE4K6Y0yKEGFH2Im7MJctOyikI1erRcwSk9xTn5Zq7Va/vdmha3HBmc4nDYhNks2dH6viWW++PraNSMN5PxkX5tOZtYf0Z/6EMJ1Xl0DIOo3lET5tN3shpcjhqIkxP51z7OkhSZVSmXoAhy21WJttmFed67GlZ6evRpoi/o0KAnZ84URh4szxLi/KfOuIQPQ6GZ2NkaL3FdKZhap;5:qZZlHsYnoQ6Pqk7Gi7tZs8BISNI+r9UwACC2+aRiXoQh8cSbY0iSuFZSMExu7qT7/Ub4YjmJJvJGWE1AFOM8QXZ2vKJqLLK9r2Z8CgiZb4MeznnxcdlRG/iNq62BQBxO/77RBiNSneEZ6Y+PvkhBeg==;24:Jkt69UNhKPI+Kbos/q/+TmDQp3oRZuSAjqLdWDrwb38R+nlkKT7J600dOSWR210eBHNa7PKT79pWyNz4pWowZayRTT2ie0+R7rvXyY/20jQ= X-Microsoft-Exchange-Diagnostics: 1;BY2PR03MB286;7:CIyGF1YneV0dPOPU5gxGty2qsk1gYH+cmPhFy1SXdno2+kc/+L0hlyU0x1DGTY1vKequOygD94DFvAknLrgDXAam0epaQu4FWH+l+2e/81buKKSgteSK8/NLjYzGKoPFOqUSM9gpOURBDt9aSWMGZYKBKJEjcRTLD9LUY71rUqZUC+agwkZziCXImC3/3ydlKdW5fhxts7xQCtIFmCKtqAPZ28SGPHgs0SbrZUPu4VmkPXDAoepvN8cMpYsNXZIRllKUqHaSKa134XBMlrXqjhugNWwtR9rSKBFAzSf6w7b4dNpjFEO27ozOdtsxB10YdMJ8RF2C8gMwkd0qkQwuzw== X-OriginatorOrg: opensource.altera.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Nov 2016 19:15:18.3526 (UTC) X-MS-Exchange-CrossTenant-Id: fbd72e03-d4a5-4110-adce-614d51f2077a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=fbd72e03-d4a5-4110-adce-614d51f2077a;Ip=[66.35.236.227];Helo=[sj-itexedge03.altera.priv.altera.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY2PR03MB286 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 18119 Lines: 668 FPGA Regions support programming FPGA under control of the Device Tree. Signed-off-by: Alan Tull Signed-off-by: Greg Kroah-Hartman --- drivers/fpga/Kconfig | 7 + drivers/fpga/Makefile | 3 + drivers/fpga/fpga-region.c | 603 ++++++++++++++++++++++++++++++++++++++++++ include/linux/fpga/fpga-mgr.h | 2 + 4 files changed, 615 insertions(+) create mode 100644 drivers/fpga/fpga-region.c diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig index 9b20f45..e0e1257 100644 --- a/drivers/fpga/Kconfig +++ b/drivers/fpga/Kconfig @@ -13,6 +13,13 @@ config FPGA if FPGA +config FPGA_REGION + tristate "FPGA Region" + depends on OF && FPGA_BRIDGE + help + FPGA Regions allow loading FPGA images under control of + the Device Tree. + config FPGA_MGR_SOCFPGA tristate "Altera SOCFPGA FPGA Manager" depends on ARCH_SOCFPGA diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile index 4baef00..8d746c3 100644 --- a/drivers/fpga/Makefile +++ b/drivers/fpga/Makefile @@ -11,3 +11,6 @@ obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA) += zynq-fpga.o # FPGA Bridge Drivers obj-$(CONFIG_FPGA_BRIDGE) += fpga-bridge.o + +# High Level Interfaces +obj-$(CONFIG_FPGA_REGION) += fpga-region.o diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c new file mode 100644 index 0000000..3222fdb --- /dev/null +++ b/drivers/fpga/fpga-region.c @@ -0,0 +1,603 @@ +/* + * FPGA Region - Device Tree support for FPGA programming under Linux + * + * Copyright (C) 2013-2016 Altera Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * struct fpga_region - FPGA Region structure + * @dev: FPGA Region device + * @mutex: enforces exclusive reference to region + * @bridge_list: list of FPGA bridges specified in region + * @info: fpga image specific information + */ +struct fpga_region { + struct device dev; + struct mutex mutex; /* for exclusive reference to region */ + struct list_head bridge_list; + struct fpga_image_info *info; +}; + +#define to_fpga_region(d) container_of(d, struct fpga_region, dev) + +static DEFINE_IDA(fpga_region_ida); +static struct class *fpga_region_class; + +static const struct of_device_id fpga_region_of_match[] = { + { .compatible = "fpga-region", }, + {}, +}; +MODULE_DEVICE_TABLE(of, fpga_region_of_match); + +static int fpga_region_of_node_match(struct device *dev, const void *data) +{ + return dev->of_node == data; +} + +/** + * fpga_region_find - find FPGA region + * @np: device node of FPGA Region + * Caller will need to put_device(®ion->dev) when done. + * Returns FPGA Region struct or NULL + */ +static struct fpga_region *fpga_region_find(struct device_node *np) +{ + struct device *dev; + + dev = class_find_device(fpga_region_class, NULL, np, + fpga_region_of_node_match); + if (!dev) + return NULL; + + return to_fpga_region(dev); +} + +/** + * fpga_region_get - get an exclusive reference to a fpga region + * @region: FPGA Region struct + * + * Caller should call fpga_region_put() when done with region. + * + * Return fpga_region struct if successful. + * Return -EBUSY if someone already has a reference to the region. + * Return -ENODEV if @np is not a FPGA Region. + */ +static struct fpga_region *fpga_region_get(struct fpga_region *region) +{ + struct device *dev = ®ion->dev; + + if (!mutex_trylock(®ion->mutex)) { + dev_dbg(dev, "%s: FPGA Region already in use\n", __func__); + return ERR_PTR(-EBUSY); + } + + get_device(dev); + of_node_get(dev->of_node); + if (!try_module_get(dev->parent->driver->owner)) { + of_node_put(dev->of_node); + put_device(dev); + mutex_unlock(®ion->mutex); + return ERR_PTR(-ENODEV); + } + + dev_dbg(®ion->dev, "get\n"); + + return region; +} + +/** + * fpga_region_put - release a reference to a region + * + * @region: FPGA region + */ +static void fpga_region_put(struct fpga_region *region) +{ + struct device *dev = ®ion->dev; + + dev_dbg(®ion->dev, "put\n"); + + module_put(dev->parent->driver->owner); + of_node_put(dev->of_node); + put_device(dev); + mutex_unlock(®ion->mutex); +} + +/** + * fpga_region_get_manager - get exclusive reference for FPGA manager + * @region: FPGA region + * + * Get FPGA Manager from "fpga-mgr" property or from ancestor region. + * + * Caller should call fpga_mgr_put() when done with manager. + * + * Return: fpga manager struct or IS_ERR() condition containing error code. + */ +static struct fpga_manager *fpga_region_get_manager(struct fpga_region *region) +{ + struct device *dev = ®ion->dev; + struct device_node *np = dev->of_node; + struct device_node *mgr_node; + struct fpga_manager *mgr; + + of_node_get(np); + while (np) { + if (of_device_is_compatible(np, "fpga-region")) { + mgr_node = of_parse_phandle(np, "fpga-mgr", 0); + if (mgr_node) { + mgr = of_fpga_mgr_get(mgr_node); + of_node_put(np); + return mgr; + } + } + np = of_get_next_parent(np); + } + of_node_put(np); + + return ERR_PTR(-EINVAL); +} + +/** + * fpga_region_get_bridges - create a list of bridges + * @region: FPGA region + * @overlay: device node of the overlay + * + * Create a list of bridges including the parent bridge and the bridges + * specified by "fpga-bridges" property. Note that the + * fpga_bridges_enable/disable/put functions are all fine with an empty list + * if that happens. + * + * Caller should call fpga_bridges_put(®ion->bridge_list) when + * done with the bridges. + * + * Return 0 for success (even if there are no bridges specified) + * or -EBUSY if any of the bridges are in use. + */ +static int fpga_region_get_bridges(struct fpga_region *region, + struct device_node *overlay) +{ + struct device *dev = ®ion->dev; + struct device_node *region_np = dev->of_node; + struct device_node *br, *np, *parent_br = NULL; + int i, ret; + + /* If parent is a bridge, add to list */ + ret = fpga_bridge_get_to_list(region_np->parent, region->info, + ®ion->bridge_list); + if (ret == -EBUSY) + return ret; + + if (!ret) + parent_br = region_np->parent; + + /* If overlay has a list of bridges, use it. */ + if (of_parse_phandle(overlay, "fpga-bridges", 0)) + np = overlay; + else + np = region_np; + + for (i = 0; ; i++) { + br = of_parse_phandle(np, "fpga-bridges", i); + if (!br) + break; + + /* If parent bridge is in list, skip it. */ + if (br == parent_br) + continue; + + /* If node is a bridge, get it and add to list */ + ret = fpga_bridge_get_to_list(br, region->info, + ®ion->bridge_list); + + /* If any of the bridges are in use, give up */ + if (ret == -EBUSY) { + fpga_bridges_put(®ion->bridge_list); + return -EBUSY; + } + } + + return 0; +} + +/** + * fpga_region_program_fpga - program FPGA + * @region: FPGA region + * @firmware_name: name of FPGA image firmware file + * @overlay: device node of the overlay + * Program an FPGA using information in the device tree. + * Function assumes that there is a firmware-name property. + * Return 0 for success or negative error code. + */ +static int fpga_region_program_fpga(struct fpga_region *region, + const char *firmware_name, + struct device_node *overlay) +{ + struct fpga_manager *mgr; + int ret; + + region = fpga_region_get(region); + if (IS_ERR(region)) { + pr_err("failed to get fpga region\n"); + return PTR_ERR(region); + } + + mgr = fpga_region_get_manager(region); + if (IS_ERR(mgr)) { + pr_err("failed to get fpga region manager\n"); + return PTR_ERR(mgr); + } + + ret = fpga_region_get_bridges(region, overlay); + if (ret) { + pr_err("failed to get fpga region bridges\n"); + goto err_put_mgr; + } + + ret = fpga_bridges_disable(®ion->bridge_list); + if (ret) { + pr_err("failed to disable region bridges\n"); + goto err_put_br; + } + + ret = fpga_mgr_firmware_load(mgr, region->info, firmware_name); + if (ret) { + pr_err("failed to load fpga image\n"); + goto err_put_br; + } + + ret = fpga_bridges_enable(®ion->bridge_list); + if (ret) { + pr_err("failed to enable region bridges\n"); + goto err_put_br; + } + + fpga_mgr_put(mgr); + fpga_region_put(region); + + return 0; + +err_put_br: + fpga_bridges_put(®ion->bridge_list); +err_put_mgr: + fpga_mgr_put(mgr); + fpga_region_put(region); + + return ret; +} + +/** + * child_regions_with_firmware + * @overlay: device node of the overlay + * + * If the overlay adds child FPGA regions, they are not allowed to have + * firmware-name property. + * + * Return 0 for OK or -EINVAL if child FPGA region adds firmware-name. + */ +static int child_regions_with_firmware(struct device_node *overlay) +{ + struct device_node *child_region; + const char *child_firmware_name; + int ret = 0; + + of_node_get(overlay); + + child_region = of_find_matching_node(overlay, fpga_region_of_match); + while (child_region) { + if (!of_property_read_string(child_region, "firmware-name", + &child_firmware_name)) { + ret = -EINVAL; + break; + } + child_region = of_find_matching_node(child_region, + fpga_region_of_match); + } + + of_node_put(child_region); + + if (ret) + pr_err("firmware-name not allowed in child FPGA region: %s", + child_region->full_name); + + return ret; +} + +/** + * fpga_region_notify_pre_apply - pre-apply overlay notification + * + * @region: FPGA region that the overlay was applied to + * @nd: overlay notification data + * + * Called after when an overlay targeted to a FPGA Region is about to be + * applied. Function will check the properties that will be added to the FPGA + * region. If the checks pass, it will program the FPGA. + * + * The checks are: + * The overlay must add either firmware-name or external-fpga-config property + * to the FPGA Region. + * + * firmware-name : program the FPGA + * external-fpga-config : FPGA is already programmed + * + * The overlay can add other FPGA regions, but child FPGA regions cannot have a + * firmware-name property since those regions don't exist yet. + * + * If the overlay that breaks the rules, notifier returns an error and the + * overlay is rejected before it goes into the main tree. + * + * Returns 0 for success or negative error code for failure. + */ +static int fpga_region_notify_pre_apply(struct fpga_region *region, + struct of_overlay_notify_data *nd) +{ + const char *firmware_name = NULL; + struct fpga_image_info *info; + int ret; + + info = devm_kzalloc(®ion->dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + region->info = info; + + /* Reject overlay if child FPGA Regions have firmware-name property */ + ret = child_regions_with_firmware(nd->overlay); + if (ret) + return ret; + + /* Read FPGA region properties from the overlay */ + if (of_property_read_bool(nd->overlay, "partial-fpga-config")) + info->flags |= FPGA_MGR_PARTIAL_RECONFIG; + + if (of_property_read_bool(nd->overlay, "external-fpga-config")) + info->flags |= FPGA_MGR_EXTERNAL_CONFIG; + + of_property_read_string(nd->overlay, "firmware-name", &firmware_name); + + of_property_read_u32(nd->overlay, "region-unfreeze-timeout-us", + &info->enable_timeout_us); + + of_property_read_u32(nd->overlay, "region-freeze-timeout-us", + &info->disable_timeout_us); + + /* If FPGA was externally programmed, don't specify firmware */ + if ((info->flags & FPGA_MGR_EXTERNAL_CONFIG) && firmware_name) { + pr_err("error: specified firmware and external-fpga-config"); + return -EINVAL; + } + + /* FPGA is already configured externally. We're done. */ + if (info->flags & FPGA_MGR_EXTERNAL_CONFIG) + return 0; + + /* If we got this far, we should be programming the FPGA */ + if (!firmware_name) { + pr_err("should specify firmware-name or external-fpga-config\n"); + return -EINVAL; + } + + return fpga_region_program_fpga(region, firmware_name, nd->overlay); +} + +/** + * fpga_region_notify_post_remove - post-remove overlay notification + * + * @region: FPGA region that was targeted by the overlay that was removed + * @nd: overlay notification data + * + * Called after an overlay has been removed if the overlay's target was a + * FPGA region. + */ +static void fpga_region_notify_post_remove(struct fpga_region *region, + struct of_overlay_notify_data *nd) +{ + fpga_bridges_disable(®ion->bridge_list); + fpga_bridges_put(®ion->bridge_list); + devm_kfree(®ion->dev, region->info); + region->info = NULL; +} + +/** + * of_fpga_region_notify - reconfig notifier for dynamic DT changes + * @nb: notifier block + * @action: notifier action + * @arg: reconfig data + * + * This notifier handles programming a FPGA when a "firmware-name" property is + * added to a fpga-region. + * + * Returns NOTIFY_OK or error if FPGA programming fails. + */ +static int of_fpga_region_notify(struct notifier_block *nb, + unsigned long action, void *arg) +{ + struct of_overlay_notify_data *nd = arg; + struct fpga_region *region; + int ret; + + switch (action) { + case OF_OVERLAY_PRE_APPLY: + pr_debug("%s OF_OVERLAY_PRE_APPLY\n", __func__); + break; + case OF_OVERLAY_POST_APPLY: + pr_debug("%s OF_OVERLAY_POST_APPLY\n", __func__); + return NOTIFY_OK; /* not for us */ + case OF_OVERLAY_PRE_REMOVE: + pr_debug("%s OF_OVERLAY_PRE_REMOVE\n", __func__); + return NOTIFY_OK; /* not for us */ + case OF_OVERLAY_POST_REMOVE: + pr_debug("%s OF_OVERLAY_POST_REMOVE\n", __func__); + break; + default: /* should not happen */ + return NOTIFY_OK; + } + + region = fpga_region_find(nd->target); + if (!region) + return NOTIFY_OK; + + ret = 0; + switch (action) { + case OF_OVERLAY_PRE_APPLY: + ret = fpga_region_notify_pre_apply(region, nd); + break; + + case OF_OVERLAY_POST_REMOVE: + fpga_region_notify_post_remove(region, nd); + break; + } + + put_device(®ion->dev); + + if (ret) + return notifier_from_errno(ret); + + return NOTIFY_OK; +} + +static struct notifier_block fpga_region_of_nb = { + .notifier_call = of_fpga_region_notify, +}; + +static int fpga_region_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct fpga_region *region; + int id, ret = 0; + + region = kzalloc(sizeof(*region), GFP_KERNEL); + if (!region) + return -ENOMEM; + + id = ida_simple_get(&fpga_region_ida, 0, 0, GFP_KERNEL); + if (id < 0) { + ret = id; + goto err_kfree; + } + + mutex_init(®ion->mutex); + INIT_LIST_HEAD(®ion->bridge_list); + + device_initialize(®ion->dev); + region->dev.class = fpga_region_class; + region->dev.parent = dev; + region->dev.of_node = np; + region->dev.id = id; + dev_set_drvdata(dev, region); + + ret = dev_set_name(®ion->dev, "region%d", id); + if (ret) + goto err_remove; + + ret = device_add(®ion->dev); + if (ret) + goto err_remove; + + of_platform_populate(np, fpga_region_of_match, NULL, ®ion->dev); + + dev_info(dev, "FPGA Region probed\n"); + + return 0; + +err_remove: + ida_simple_remove(&fpga_region_ida, id); +err_kfree: + kfree(region); + + return ret; +} + +static int fpga_region_remove(struct platform_device *pdev) +{ + struct fpga_region *region = platform_get_drvdata(pdev); + + device_unregister(®ion->dev); + + return 0; +} + +static struct platform_driver fpga_region_driver = { + .probe = fpga_region_probe, + .remove = fpga_region_remove, + .driver = { + .name = "fpga-region", + .of_match_table = of_match_ptr(fpga_region_of_match), + }, +}; + +static void fpga_region_dev_release(struct device *dev) +{ + struct fpga_region *region = to_fpga_region(dev); + + ida_simple_remove(&fpga_region_ida, region->dev.id); + kfree(region); +} + +/** + * fpga_region_init - init function for fpga_region class + * Creates the fpga_region class and registers a reconfig notifier. + */ +static int __init fpga_region_init(void) +{ + int ret; + + fpga_region_class = class_create(THIS_MODULE, "fpga_region"); + if (IS_ERR(fpga_region_class)) + return PTR_ERR(fpga_region_class); + + fpga_region_class->dev_release = fpga_region_dev_release; + + ret = of_overlay_notifier_register(&fpga_region_of_nb); + if (ret) + goto err_class; + + ret = platform_driver_register(&fpga_region_driver); + if (ret) + goto err_plat; + + return 0; + +err_plat: + of_overlay_notifier_unregister(&fpga_region_of_nb); +err_class: + class_destroy(fpga_region_class); + ida_destroy(&fpga_region_ida); + return ret; +} + +static void __exit fpga_region_exit(void) +{ + platform_driver_unregister(&fpga_region_driver); + of_overlay_notifier_unregister(&fpga_region_of_nb); + class_destroy(fpga_region_class); + ida_destroy(&fpga_region_ida); +} + +subsys_initcall(fpga_region_init); +module_exit(fpga_region_exit); + +MODULE_DESCRIPTION("FPGA Region"); +MODULE_AUTHOR("Alan Tull "); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h index 5580318..96a1a33 100644 --- a/include/linux/fpga/fpga-mgr.h +++ b/include/linux/fpga/fpga-mgr.h @@ -65,8 +65,10 @@ enum fpga_mgr_states { /* * FPGA Manager flags * FPGA_MGR_PARTIAL_RECONFIG: do partial reconfiguration if supported + * FPGA_MGR_EXTERNAL_CONFIG: FPGA has been configured prior to Linux booting */ #define FPGA_MGR_PARTIAL_RECONFIG BIT(0) +#define FPGA_MGR_EXTERNAL_CONFIG BIT(1) /** * struct fpga_image_info - information specific to a FPGA image -- 1.9.1