{"id":2225770,"url":"http://patchwork.ozlabs.org/api/patches/2225770/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/patch/20260421-io_projection-v2-5-4c251c692ef4@garyguo.net/","project":{"id":28,"url":"http://patchwork.ozlabs.org/api/projects/28/?format=json","name":"Linux PCI development","link_name":"linux-pci","list_id":"linux-pci.vger.kernel.org","list_email":"linux-pci@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20260421-io_projection-v2-5-4c251c692ef4@garyguo.net>","list_archive_url":null,"date":"2026-04-21T14:56:16","name":"[v2,05/11] rust: io: restrict untyped IO access and `register!` to `Region`","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"15fbcbf39bb258a6cea9e99f966340c37738de4f","submitter":{"id":76823,"url":"http://patchwork.ozlabs.org/api/people/76823/?format=json","name":"Gary Guo","email":"gary@garyguo.net"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-pci/patch/20260421-io_projection-v2-5-4c251c692ef4@garyguo.net/mbox/","series":[{"id":500833,"url":"http://patchwork.ozlabs.org/api/series/500833/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/list/?series=500833","date":"2026-04-21T14:56:19","name":"rust: I/O type generalization and projection","version":2,"mbox":"http://patchwork.ozlabs.org/series/500833/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2225770/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2225770/checks/","tags":{},"related":[],"headers":{"Return-Path":"\n <linux-pci+bounces-52840-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-pci@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=garyguo.net header.i=@garyguo.net header.a=rsa-sha256\n header.s=selector1 header.b=cm+4JCk3;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c15:e001:75::12fc:5321; helo=sin.lore.kernel.org;\n envelope-from=linux-pci+bounces-52840-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net\n header.b=\"cm+4JCk3\"","smtp.subspace.kernel.org;\n arc=fail smtp.client-ip=52.101.196.131","smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=garyguo.net","smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=garyguo.net","dkim=none (message not signed)\n header.d=none;dmarc=none action=none header.from=garyguo.net;"],"Received":["from sin.lore.kernel.org (sin.lore.kernel.org\n [IPv6:2600:3c15:e001:75::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g0QT45FmNz1yCv\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 00:58:00 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sin.lore.kernel.org (Postfix) with ESMTP id EB984301372C\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 21 Apr 2026 14:56:41 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 188C43A257C;\n\tTue, 21 Apr 2026 14:56:35 +0000 (UTC)","from LO3P265CU004.outbound.protection.outlook.com\n (mail-uksouthazon11020131.outbound.protection.outlook.com [52.101.196.131])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 1181F3D9038;\n\tTue, 21 Apr 2026 14:56:32 +0000 (UTC)","from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:488::16)\n by CWLP265MB5674.GBRP265.PROD.OUTLOOK.COM (2603:10a6:400:1b0::13) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9846.16; Tue, 21 Apr\n 2026 14:56:29 +0000","from LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM\n ([fe80::1c3:ceba:21b4:9986]) by LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM\n ([fe80::1c3:ceba:21b4:9986%4]) with mapi id 15.20.9846.016; Tue, 21 Apr 2026\n 14:56:29 +0000"],"ARC-Seal":["i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1776783395; cv=fail;\n b=RPQLBwhMAZxc9jEg6kBxbyN2U0Mp2nhuP3BxiNtHKSm/3S6R9iaFBmeBJwqbF+xpN2jq7oL56qAUa8tWaGb5Yy5wnrtGH8yWIRDLleYCGV2majWp9ME8kj5rOLHXFbUNSvm6WD+/S+ZEPCy6PeQEGQPnM1M+qkMoeZGQ1OWWFf8=","i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;\n b=S1JnXNn4Zb26InXVpjl6gmdj4bUlVRvWJieswDgDL03Bp3gc61Qi/MGW/fgKc6wGd5tBwZP6tmnWCMJu+vFbL+ddc2bHrCvLG6fUCpp5VLZBbHz6qgX4VIB3PbwfiUrmw166gTRp2HoGMMzRHXTr7zXxgTpjI0HdzVNE0aNNBYfGJ0eXefJHO5jz+nBTpOEfhxdw/c2J/Pv8UQGD1FqaOAHvV90DyysydBLFmJTBJ+3MRllDu3M4D9iXaGHr0ecbJzExN3PY0MEqZdlYPALLtggKSwahLuXd0wMNlf6V+V9zNEzupvLySQ0DYNaum0tFFytfQ+TkaDyNLkbsr0F3/A=="],"ARC-Message-Signature":["i=2; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1776783395; c=relaxed/simple;\n\tbh=5GVZfqmlRD7YS7IuSASRsDrAHqXip3Elc7FIgJl4J90=;\n\th=From:Date:Subject:Content-Type:Message-Id:References:In-Reply-To:\n\t To:Cc:MIME-Version;\n b=uvE+8RaZ6eI76Hr9Mzad/kFYK1OvNlwqXuKKOe7u1jxoxQ6zeZ7QVqKt0vnvh1SUViY5rydPbnc5FC4H6ETVW3uFxqFvTP1EW2bEE/gSa9ZjK9w4/lEuBGOREr5TSFzZfoMBhxcnAaYa+LirWrFHTUFhWVrFkeAckVc16tAwE6A=","i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector10001;\n 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;\n bh=gz3InflAKtslVQJSJgHeMm1kKTjdd/kLAIC9qXKn59Q=;\n b=h8BP9FqLKnS33bacO6FUK3uryFXX/cTLkv3g1myeFfRCscTURDnbH+ERuzKZc8bRxf9ngMKwLIPWWg/EyNKegN/E+AP83YQrywVJVUHijUYZiqRRLhDZiwsqkkhogJkooqyHEs9ng7f2DlDwQ9GrS4R7ldKHlpUh0F18VcTRvEoLyP7McufxP2016QEXXieNxj6lA0z1Ks499lcrzobH0FJwfEpMv5EOLn03G+PggWcj7LDmoG8PB/bJudK/hXzDc1ltAKofNyvFhohqzGNXfMCHmG2u6/B/A2nSlwkAodJ7yS0b0XlOyKe7mUTw1JkJAEZz4ENW+7hsERsrag9kwA=="],"ARC-Authentication-Results":["i=2; smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=garyguo.net;\n spf=pass smtp.mailfrom=garyguo.net;\n dkim=pass (1024-bit key) header.d=garyguo.net header.i=@garyguo.net\n header.b=cm+4JCk3; arc=fail smtp.client-ip=52.101.196.131","i=1; mx.microsoft.com 1; spf=pass\n smtp.mailfrom=garyguo.net; dmarc=pass action=none header.from=garyguo.net;\n dkim=pass header.d=garyguo.net; arc=none"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=garyguo.net;\n s=selector1;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=gz3InflAKtslVQJSJgHeMm1kKTjdd/kLAIC9qXKn59Q=;\n b=cm+4JCk3ICMruZutIeOuFVyPP3lgT6qN4jJGEwjpooGYqVBbloLK0IwK1YBygtpTsJWIejCvd5/HXksoz8IL5iXDl9hoqGQFrgNh5a214o/qRNr2mdwYW3hWgKZ8bczytII6y1cbtkW0P+0dc3QmZogYxSHZUtXeAoe5JKE1AO0=","From":"Gary Guo <gary@garyguo.net>","Date":"Tue, 21 Apr 2026 15:56:16 +0100","Subject":"[PATCH v2 05/11] rust: io: restrict untyped IO access and\n `register!` to `Region`","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"7bit","Message-Id":"<20260421-io_projection-v2-5-4c251c692ef4@garyguo.net>","References":"<20260421-io_projection-v2-0-4c251c692ef4@garyguo.net>","In-Reply-To":"<20260421-io_projection-v2-0-4c251c692ef4@garyguo.net>","To":"Greg Kroah-Hartman <gregkh@linuxfoundation.org>,\n  \"Rafael J. Wysocki\" <rafael@kernel.org>, Danilo Krummrich <dakr@kernel.org>,\n  Miguel Ojeda <ojeda@kernel.org>, Boqun Feng <boqun@kernel.org>,\n  Gary Guo <gary@garyguo.net>,\n =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= <bjorn3_gh@protonmail.com>,\n  Benno Lossin <lossin@kernel.org>, Andreas Hindborg <a.hindborg@kernel.org>,\n  Alice Ryhl <aliceryhl@google.com>, Trevor Gross <tmgross@umich.edu>,\n  Daniel Almeida <daniel.almeida@collabora.com>,\n  Bjorn Helgaas <bhelgaas@google.com>,\n =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= <kwilczynski@kernel.org>,\n  Abdiel Janulgue <abdiel.janulgue@gmail.com>,\n  Robin Murphy <robin.murphy@arm.com>,\n  Alexandre Courbot <acourbot@nvidia.com>, David Airlie <airlied@gmail.com>,\n  Simona Vetter <simona@ffwll.ch>","Cc":"driver-core@lists.linux.dev, rust-for-linux@vger.kernel.org,\n linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org,\n nouveau@lists.freedesktop.org, dri-devel@lists.freedesktop.org","X-Mailer":"b4 0.15.1","X-Developer-Signature":"v=1; a=ed25519-sha256; t=1776783386; l=13259;\n i=gary@garyguo.net; s=20221204; h=from:subject:message-id;\n bh=5GVZfqmlRD7YS7IuSASRsDrAHqXip3Elc7FIgJl4J90=;\n b=c1qQ5DpiFXu6Q0zRPZm7320fqpB78rfHQksb0sudcivMAAKQYhzpxwNBIUibr1/TiYsVppY+p\n 7AbPH/XqylgBDkvynB8TgT9tMoNc/xeftqQZz0KLpoay1KVl9dinsf4","X-Developer-Key":"i=gary@garyguo.net; a=ed25519;\n pk=vB3uIX95SM4eVrIqo1DWNWKDKD2xzB+yLLLr0yOPYMo=","X-ClientProxiedBy":"LO4P123CA0142.GBRP123.PROD.OUTLOOK.COM\n (2603:10a6:600:193::21) To LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM\n (2603:10a6:600:488::16)","Precedence":"bulk","X-Mailing-List":"linux-pci@vger.kernel.org","List-Id":"<linux-pci.vger.kernel.org>","List-Subscribe":"<mailto:linux-pci+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-pci+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","X-MS-PublicTrafficType":"Email","X-MS-TrafficTypeDiagnostic":"LOVP265MB8871:EE_|CWLP265MB5674:EE_","X-MS-Office365-Filtering-Correlation-Id":"8a6122e1-0478-49c1-b797-08de9fb62b1e","X-MS-Exchange-SenderADCheck":"1","X-MS-Exchange-AntiSpam-Relay":"0","X-Microsoft-Antispam":"\n\tBCL:0;ARA:13230040|1800799024|376014|7416014|10070799003|366016|921020|22082099003|18002099003|56012099003|18096099003;","X-Microsoft-Antispam-Message-Info":"\n\tw9F7UZYmeXl2Nk4FbIOOuMmyidCSMmgu6s8FekySQxwyaQ6ELAipScnds2x+DwaHZqXtMr/1dcOh+wujm9wZu49HsOAipnwTavvgFJoNLxpExu9FQwJeaOBOBYQsHeOR2a9Br5ig7WzBgblqAYBfkmSwxpqwEocJ6JlN2C1Jmpoh56fKWse/gaaqy1e/GU06bzY5ii4+MVTTZvi9wYNfLXY3LrVjR/T0SjfdDpoj89ee1PqxQyLUT2MON/QczapouZ1agggk0ANcFscc3A24OORaw/nC6OAzSe3w6+vbzlBtmzORo5q9a6Nar+Ffv12vMbEfUNbRFb5iGNm/eIoEtcs3R+8vdtdwbpe0f7utuz2ya7taPX3G5QdPB9W/K0kUOnMUwpCHEcQ2WjtE8W6+f9O07BvPZXEuKNLG4JKHqjZYL/+FwDedWUVai1+tFgQPqo9vk9sy5zo/tQ3M4+iPmL2MnQuNTyWPhAkx2/1vD/T8sI41AVfNtwM93csiRCEAkix43j2bk7jJJatEvgBMez+ln2CCUZSjSX8V8kabICdA5PuLHOA8LQJFrqq22suOvjOgMw6cLisllYpmoynEiJilXwgMR/+f6PXR0rjuq2R7GqNMm4Zje018TdnymwPmvEchooVfA68Z/2wjIYvrJcJlNN4AiUltn1RTsnv7DlUdaMhWAohyTnRsDAknLag52saWmzY+PkDSNyQKzd4wFROksSKIQDznzQyhQ64j90GKiH3hIjkmfDcIldEZFNRcvSQZ6iH8LND9r2clqzUueQ==","X-Forefront-Antispam-Report":"\n\tCIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(376014)(7416014)(10070799003)(366016)(921020)(22082099003)(18002099003)(56012099003)(18096099003);DIR:OUT;SFP:1102;","X-MS-Exchange-AntiSpam-MessageData-ChunkCount":"1","X-MS-Exchange-AntiSpam-MessageData-0":"=?utf-8?q?fb5eDCuNTR58enYShu3Vn8JG9Kh/?=\n\t=?utf-8?q?YAMI86XklU5wFQLQZ3ahtM4MbjGpsID8d9OIdYP9aMe9g8kS/gWVV0xmDIw3nz3eG?=\n\t=?utf-8?q?6YHN0Y24yD93pI52zJDIrHZ2qa0WBTVFC6ZBFXsb2nLxQ3Cl5P21yRG3ZZL3/L5yC?=\n\t=?utf-8?q?14gfUB6hPaRDFqrRABjzDCucU4yN391mAJePhDAFyTKpb5HrQGhVfR94bPAMpFrsa?=\n\t=?utf-8?q?C8Qit75NdOyEhw8z2atCeoN9iSCH9y+U5j13RwzL6fj962wP8ttOS41zqEA1ZVKom?=\n\t=?utf-8?q?zlZ7TrDSawWcM1NVGwO9sM5ZpJvENAtMdHQX2MT5/4E8l89O6vxJWO5VYAGxAJj03?=\n\t=?utf-8?q?JB/MbeB44pd+IwPYnxewnm+dV4/fu3BFyC2pulqubYxp6hlpC1ptNBUHYRqA7J1kk?=\n\t=?utf-8?q?xZGao7ou3R2DVICInrU8RfqZDBE4HDHV7NMe6HmgTSDxsEPkdQB22wlzI0PB+ETFm?=\n\t=?utf-8?q?4ktkuZP2xQsWtF9CAHBf8ZarLrN3KRHUiXQI0cG5kTrIhB1y7NXk8QZSNgSRURO/r?=\n\t=?utf-8?q?HngZccinSMkAcHtu3wWiNzajbdGaNcXcm9xjZBQbw3ESrA89AsFH+akwVATI5TFjO?=\n\t=?utf-8?q?0KOU4ukMCenAR9tyDrmy4A2sAg/vRYs2xWhzH+S2A2L1CMIXy5SBp5jE0Vq55MEEk?=\n\t=?utf-8?q?CAsKxEJF7JlPKdM9hnrR/X5kBZPNb6q0M4WeI3XVp+8807hjvGjmuz+P5c8AAyU+K?=\n\t=?utf-8?q?MR4wa7ewTYt5SyQlRDLZ5QT7zkuqPPBUqbmj1p4o92KuWrLdz+ixhdZA6A2Gx3Xd3?=\n\t=?utf-8?q?A/9l74GwgiWWM8ElKbXFGdVWuGd4W6fN0SiC+c+W5qG2Euk7knlPLL0hZbCLWY31n?=\n\t=?utf-8?q?2VMc4rEzECrNTn//0EUVMNNRBrFaG/lfdDbosams6MJ3hz4gH8A4iVsT6PZSPPobR?=\n\t=?utf-8?q?0bNxZVeImMQ5LyCDGR270uIJ2f55TpA1sKr6bQ+pMgGLQaPRIjnIAbZOFG9IaWoaS?=\n\t=?utf-8?q?lzmLAn3GbS9C+R0YU1V4A+1YUvwtXMYzo5nQt2WngiUMrV0eSPFdMLkck2+DjeVWp?=\n\t=?utf-8?q?Itd0tt0cobHhBCFwEt198CskUBGa4bH9fLxq+dsw0oxGdzpcnZ9lzMY3VM1wbqQ7a?=\n\t=?utf-8?q?WpygQjILkeBs+ssantcYYlEqMM5DQdt2lo4vAuBYYe+F8ms+vBacnoupyB1htOvww?=\n\t=?utf-8?q?HCB3u1ZcATAH/zEWrXb43uD4Reun0ePvFGcuDVJwfwXypM/feGdyfLj13IHtmMAiP?=\n\t=?utf-8?q?9xfqZ02ciQJ+rl0RqfIFbumbW4DSpgWNmK5QfbLXuDOapp4Jd03olt7kmPwEx+g9S?=\n\t=?utf-8?q?C020gXM26iPRZ7UCFY7LEZ9WX0btIcmquY43iseq94bUXrVR87jfT6Uwwd8XxmYlA?=\n\t=?utf-8?q?vHN9HPNvh6TMj7E0pKhjbXR6Ukugh70hdKbPCAuUgtalbn/BN0NN3k1Jy/JkwRkly?=\n\t=?utf-8?q?mD21ZmWP8oVOgnjvXUZd3WoEeV2pT5YKLivgTzJunnTSB+Au9+ZtAoAL1yUPuCSLW?=\n\t=?utf-8?q?1r76bezq5k2ce0Rqr05qsuFKRgT4sglSsHRlq4o+qz094pknngSZ+f82GTr4pEZ2p?=\n\t=?utf-8?q?WcZJKzdhxW0Wjmp0xW7v6efRXJAHkxza7NM8619KHXS/LFwdVO+ML6q+7dYawfm6F?=\n\t=?utf-8?q?/omduYKCAGeZHeNZHukbUBq4+UglerdxVpkywcs1QpgFrOsUTxUAr0EayMT3bcCXg?=\n\t=?utf-8?q?eplPCN3rQD10LhBLNzGzLmMbM5Yu818Q=3D=3D?=","X-OriginatorOrg":"garyguo.net","X-MS-Exchange-CrossTenant-Network-Message-Id":"\n 8a6122e1-0478-49c1-b797-08de9fb62b1e","X-MS-Exchange-CrossTenant-AuthSource":"LOVP265MB8871.GBRP265.PROD.OUTLOOK.COM","X-MS-Exchange-CrossTenant-AuthAs":"Internal","X-MS-Exchange-CrossTenant-OriginalArrivalTime":"21 Apr 2026 14:56:29.0683\n (UTC)","X-MS-Exchange-CrossTenant-FromEntityHeader":"Hosted","X-MS-Exchange-CrossTenant-Id":"bbc898ad-b10f-4e10-8552-d9377b823d45","X-MS-Exchange-CrossTenant-MailboxType":"HOSTED","X-MS-Exchange-CrossTenant-UserPrincipalName":"\n 6vlJU61SMvVn1TYtMLIxUaMkpVCJ4xodcqxXU3/UsitaErlu79WNV+uwfUMdnb8hZTwGpTeq5urd7eoD2N4Xwg==","X-MS-Exchange-Transport-CrossTenantHeadersStamped":"CWLP265MB5674"},"content":"Currently the `Io` trait exposes a bunch of untyped IO accesses, but if the\n`Io` region itself is typed, then it might be weird to have\n\n    let io: Mmio<u32> = /* ... */;\n    io.read8(1);\n\nwhile not unsound, it is surely strange. Thus, restrict the untyped methods\nand also the register macro to `Region` type only.\n\nThe way it is implemented is by adding a generic type to `IoLoc`. This also\npaves the way to add typed register blocks in the future; for example, we\ncould use this mechanism to block driver A's `register!()` generated macro\nfrom being used on driver B's MMIO. The same mechanism could be used for\nrelative IO registers. These are future opoortunities, and for this patch I\njust restricted everything to require `IoLoc<Region<SIZE>, _>`.\n\nSuggested-by: Alexandre Courbot <acourbot@nvidia.com>\nLink: https://lore.kernel.org/rust-for-linux/DHLB3RO3OSF5.2R7F27U99BKLN@nvidia.com/\nSigned-off-by: Gary Guo <gary@garyguo.net>\n---\n rust/kernel/io.rs          | 47 +++++++++++++++++++++++++++++++---------------\n rust/kernel/io/register.rs | 21 ++++++++++++---------\n 2 files changed, 44 insertions(+), 24 deletions(-)","diff":"diff --git a/rust/kernel/io.rs b/rust/kernel/io.rs\nindex c6d30c5b4e10..a13be8c5fd2d 100644\n--- a/rust/kernel/io.rs\n+++ b/rust/kernel/io.rs\n@@ -238,15 +238,16 @@ pub trait IoCapable<T> {\n /// (for primitive types like [`u32`]) and typed ones (like those generated by the [`register!`]\n /// macro).\n ///\n-/// An `IoLoc<T>` carries three pieces of information:\n+/// An `IoLoc<Base, T>` carries the following pieces of information:\n ///\n+/// - The valid `Base` to operate on. For most registers, this should be [`Region`].\n /// - The offset to access (returned by [`IoLoc::offset`]),\n /// - The width of the access (determined by [`IoLoc::IoType`]),\n /// - The type `T` in which the raw data is returned or provided.\n ///\n /// `T` and `IoLoc::IoType` may differ: for instance, a typed register has `T` = the register type\n /// with its bitfields, and `IoType` = its backing primitive (e.g. `u32`).\n-pub trait IoLoc<T> {\n+pub trait IoLoc<Base: ?Sized, T> {\n     /// Size ([`u8`], [`u16`], etc) of the I/O performed on the returned [`offset`](IoLoc::offset).\n     type IoType: Into<T> + From<T>;\n \n@@ -254,12 +255,12 @@ pub trait IoLoc<T> {\n     fn offset(self) -> usize;\n }\n \n-/// Implements [`IoLoc<$ty>`] for [`usize`], allowing [`usize`] to be used as a parameter of\n-/// [`Io::read`] and [`Io::write`].\n+/// Implements [`IoLoc<Region<SIZE>, $ty>`] for [`usize`], allowing [`usize`] to be used as a\n+/// parameter of [`Io::read`] and [`Io::write`].\n macro_rules! impl_usize_ioloc {\n     ($($ty:ty),*) => {\n         $(\n-            impl IoLoc<$ty> for usize {\n+            impl<const SIZE: usize> IoLoc<Region<SIZE>, $ty> for usize {\n                 type IoType = $ty;\n \n                 #[inline(always)]\n@@ -328,6 +329,7 @@ fn io_addr<U>(&self, offset: usize) -> Result<*mut U> {\n     #[inline(always)]\n     fn try_read8(&self, offset: usize) -> Result<u8>\n     where\n+        usize: IoLoc<Self::Type, u8, IoType = u8>,\n         Self: IoCapable<u8>,\n     {\n         self.try_read(offset)\n@@ -337,6 +339,7 @@ fn try_read8(&self, offset: usize) -> Result<u8>\n     #[inline(always)]\n     fn try_read16(&self, offset: usize) -> Result<u16>\n     where\n+        usize: IoLoc<Self::Type, u16, IoType = u16>,\n         Self: IoCapable<u16>,\n     {\n         self.try_read(offset)\n@@ -346,6 +349,7 @@ fn try_read16(&self, offset: usize) -> Result<u16>\n     #[inline(always)]\n     fn try_read32(&self, offset: usize) -> Result<u32>\n     where\n+        usize: IoLoc<Self::Type, u32, IoType = u32>,\n         Self: IoCapable<u32>,\n     {\n         self.try_read(offset)\n@@ -355,6 +359,7 @@ fn try_read32(&self, offset: usize) -> Result<u32>\n     #[inline(always)]\n     fn try_read64(&self, offset: usize) -> Result<u64>\n     where\n+        usize: IoLoc<Self::Type, u64, IoType = u64>,\n         Self: IoCapable<u64>,\n     {\n         self.try_read(offset)\n@@ -364,6 +369,7 @@ fn try_read64(&self, offset: usize) -> Result<u64>\n     #[inline(always)]\n     fn try_write8(&self, value: u8, offset: usize) -> Result\n     where\n+        usize: IoLoc<Self::Type, u8, IoType = u8>,\n         Self: IoCapable<u8>,\n     {\n         self.try_write(offset, value)\n@@ -373,6 +379,7 @@ fn try_write8(&self, value: u8, offset: usize) -> Result\n     #[inline(always)]\n     fn try_write16(&self, value: u16, offset: usize) -> Result\n     where\n+        usize: IoLoc<Self::Type, u16, IoType = u16>,\n         Self: IoCapable<u16>,\n     {\n         self.try_write(offset, value)\n@@ -382,6 +389,7 @@ fn try_write16(&self, value: u16, offset: usize) -> Result\n     #[inline(always)]\n     fn try_write32(&self, value: u32, offset: usize) -> Result\n     where\n+        usize: IoLoc<Self::Type, u32, IoType = u32>,\n         Self: IoCapable<u32>,\n     {\n         self.try_write(offset, value)\n@@ -391,6 +399,7 @@ fn try_write32(&self, value: u32, offset: usize) -> Result\n     #[inline(always)]\n     fn try_write64(&self, value: u64, offset: usize) -> Result\n     where\n+        usize: IoLoc<Self::Type, u64, IoType = u64>,\n         Self: IoCapable<u64>,\n     {\n         self.try_write(offset, value)\n@@ -400,6 +409,7 @@ fn try_write64(&self, value: u64, offset: usize) -> Result\n     #[inline(always)]\n     fn read8(&self, offset: usize) -> u8\n     where\n+        usize: IoLoc<Self::Type, u8, IoType = u8>,\n         Self: IoCapable<u8>,\n     {\n         self.read(offset)\n@@ -409,6 +419,7 @@ fn read8(&self, offset: usize) -> u8\n     #[inline(always)]\n     fn read16(&self, offset: usize) -> u16\n     where\n+        usize: IoLoc<Self::Type, u16, IoType = u16>,\n         Self: IoCapable<u16>,\n     {\n         self.read(offset)\n@@ -418,6 +429,7 @@ fn read16(&self, offset: usize) -> u16\n     #[inline(always)]\n     fn read32(&self, offset: usize) -> u32\n     where\n+        usize: IoLoc<Self::Type, u32, IoType = u32>,\n         Self: IoCapable<u32>,\n     {\n         self.read(offset)\n@@ -427,6 +439,7 @@ fn read32(&self, offset: usize) -> u32\n     #[inline(always)]\n     fn read64(&self, offset: usize) -> u64\n     where\n+        usize: IoLoc<Self::Type, u64, IoType = u64>,\n         Self: IoCapable<u64>,\n     {\n         self.read(offset)\n@@ -436,6 +449,7 @@ fn read64(&self, offset: usize) -> u64\n     #[inline(always)]\n     fn write8(&self, value: u8, offset: usize)\n     where\n+        usize: IoLoc<Self::Type, u8, IoType = u8>,\n         Self: IoCapable<u8>,\n     {\n         self.write(offset, value)\n@@ -445,6 +459,7 @@ fn write8(&self, value: u8, offset: usize)\n     #[inline(always)]\n     fn write16(&self, value: u16, offset: usize)\n     where\n+        usize: IoLoc<Self::Type, u16, IoType = u16>,\n         Self: IoCapable<u16>,\n     {\n         self.write(offset, value)\n@@ -454,6 +469,7 @@ fn write16(&self, value: u16, offset: usize)\n     #[inline(always)]\n     fn write32(&self, value: u32, offset: usize)\n     where\n+        usize: IoLoc<Self::Type, u32, IoType = u32>,\n         Self: IoCapable<u32>,\n     {\n         self.write(offset, value)\n@@ -463,6 +479,7 @@ fn write32(&self, value: u32, offset: usize)\n     #[inline(always)]\n     fn write64(&self, value: u64, offset: usize)\n     where\n+        usize: IoLoc<Self::Type, u64, IoType = u64>,\n         Self: IoCapable<u64>,\n     {\n         self.write(offset, value)\n@@ -494,7 +511,7 @@ fn write64(&self, value: u64, offset: usize)\n     #[inline(always)]\n     fn try_read<T, L>(&self, location: L) -> Result<T>\n     where\n-        L: IoLoc<T>,\n+        L: IoLoc<Self::Type, T>,\n         Self: IoCapable<L::IoType>,\n     {\n         let address = self.io_addr::<L::IoType>(location.offset())?;\n@@ -529,7 +546,7 @@ fn try_read<T, L>(&self, location: L) -> Result<T>\n     #[inline(always)]\n     fn try_write<T, L>(&self, location: L, value: T) -> Result\n     where\n-        L: IoLoc<T>,\n+        L: IoLoc<Self::Type, T>,\n         Self: IoCapable<L::IoType>,\n     {\n         let address = self.io_addr::<L::IoType>(location.offset())?;\n@@ -576,8 +593,8 @@ fn try_write<T, L>(&self, location: L, value: T) -> Result\n     #[inline(always)]\n     fn try_write_reg<T, L, V>(&self, value: V) -> Result\n     where\n-        L: IoLoc<T>,\n-        V: LocatedRegister<Location = L, Value = T>,\n+        L: IoLoc<Self::Type, T>,\n+        V: LocatedRegister<Self::Type, Location = L, Value = T>,\n         Self: IoCapable<L::IoType>,\n     {\n         let (location, value) = value.into_io_op();\n@@ -610,7 +627,7 @@ fn try_write_reg<T, L, V>(&self, value: V) -> Result\n     #[inline(always)]\n     fn try_update<T, L, F>(&self, location: L, f: F) -> Result\n     where\n-        L: IoLoc<T>,\n+        L: IoLoc<Self::Type, T>,\n         Self: IoCapable<L::IoType>,\n         F: FnOnce(T) -> T,\n     {\n@@ -650,7 +667,7 @@ fn try_update<T, L, F>(&self, location: L, f: F) -> Result\n     #[inline(always)]\n     fn read<T, L>(&self, location: L) -> T\n     where\n-        L: IoLoc<T>,\n+        L: IoLoc<Self::Type, T>,\n         Self: IoCapable<L::IoType>,\n     {\n         let address = self.io_addr_assert::<L::IoType>(location.offset());\n@@ -683,7 +700,7 @@ fn read<T, L>(&self, location: L) -> T\n     #[inline(always)]\n     fn write<T, L>(&self, location: L, value: T)\n     where\n-        L: IoLoc<T>,\n+        L: IoLoc<Self::Type, T>,\n         Self: IoCapable<L::IoType>,\n     {\n         let address = self.io_addr_assert::<L::IoType>(location.offset());\n@@ -727,8 +744,8 @@ fn write<T, L>(&self, location: L, value: T)\n     #[inline(always)]\n     fn write_reg<T, L, V>(&self, value: V)\n     where\n-        L: IoLoc<T>,\n-        V: LocatedRegister<Location = L, Value = T>,\n+        L: IoLoc<Self::Type, T>,\n+        V: LocatedRegister<Self::Type, Location = L, Value = T>,\n         Self: IoCapable<L::IoType>,\n     {\n         let (location, value) = value.into_io_op();\n@@ -761,7 +778,7 @@ fn write_reg<T, L, V>(&self, value: V)\n     #[inline(always)]\n     fn update<T, L, F>(&self, location: L, f: F)\n     where\n-        L: IoLoc<T>,\n+        L: IoLoc<Self::Type, T>,\n         Self: IoCapable<L::IoType>,\n         F: FnOnce(T) -> T,\n     {\ndiff --git a/rust/kernel/io/register.rs b/rust/kernel/io/register.rs\nindex 1a407fc35edc..5a7d44c51477 100644\n--- a/rust/kernel/io/register.rs\n+++ b/rust/kernel/io/register.rs\n@@ -113,6 +113,8 @@\n \n use kernel::build_assert;\n \n+use super::Region;\n+\n /// Trait implemented by all registers.\n pub trait Register: Sized {\n     /// Backing primitive type of the register.\n@@ -129,7 +131,7 @@ pub trait FixedRegister: Register {}\n \n /// Allows `()` to be used as the `location` parameter of [`Io::write`](super::Io::write) when\n /// passing a [`FixedRegister`] value.\n-impl<T> IoLoc<T> for ()\n+impl<const SIZE: usize, T> IoLoc<Region<SIZE>, T> for ()\n where\n     T: FixedRegister,\n {\n@@ -143,7 +145,7 @@ fn offset(self) -> usize {\n \n /// A [`FixedRegister`] carries its location in its type. Thus `FixedRegister` values can be used\n /// as an [`IoLoc`].\n-impl<T> IoLoc<T> for T\n+impl<const SIZE: usize, T> IoLoc<Region<SIZE>, T> for T\n where\n     T: FixedRegister,\n {\n@@ -168,7 +170,7 @@ pub const fn new() -> Self {\n     }\n }\n \n-impl<T> IoLoc<T> for FixedRegisterLoc<T>\n+impl<const SIZE: usize, T> IoLoc<Region<SIZE>, T> for FixedRegisterLoc<T>\n where\n     T: FixedRegister,\n {\n@@ -239,7 +241,8 @@ const fn offset(self) -> usize {\n     }\n }\n \n-impl<T, B> IoLoc<T> for RelativeRegisterLoc<T, B>\n+// FIXME: Make use of `Base` type parameter of `Region` directly.\n+impl<const SIZE: usize, T, B> IoLoc<Region<SIZE>, T> for RelativeRegisterLoc<T, B>\n where\n     T: RelativeRegister,\n     B: RegisterBase<T::BaseFamily> + ?Sized,\n@@ -283,7 +286,7 @@ pub fn try_new(idx: usize) -> Option<Self> {\n     }\n }\n \n-impl<T> IoLoc<T> for RegisterArrayLoc<T>\n+impl<const SIZE: usize, T> IoLoc<Region<SIZE>, T> for RegisterArrayLoc<T>\n where\n     T: RegisterArray,\n {\n@@ -370,7 +373,7 @@ pub fn try_at(self, idx: usize) -> Option<RelativeRegisterArrayLoc<T, B>> {\n     }\n }\n \n-impl<T, B> IoLoc<T> for RelativeRegisterArrayLoc<T, B>\n+impl<const SIZE: usize, T, B> IoLoc<Region<SIZE>, T> for RelativeRegisterArrayLoc<T, B>\n where\n     T: RelativeRegisterArray,\n     B: RegisterBase<T::BaseFamily> + ?Sized,\n@@ -387,18 +390,18 @@ fn offset(self) -> usize {\n /// which to write it.\n ///\n /// Implementors can be used with [`Io::write_reg`](super::Io::write_reg).\n-pub trait LocatedRegister {\n+pub trait LocatedRegister<Base: ?Sized> {\n     /// Register value to write.\n     type Value: Register;\n     /// Full location information at which to write the value.\n-    type Location: IoLoc<Self::Value>;\n+    type Location: IoLoc<Base, Self::Value>;\n \n     /// Consumes `self` and returns a `(location, value)` tuple describing a valid I/O write\n     /// operation.\n     fn into_io_op(self) -> (Self::Location, Self::Value);\n }\n \n-impl<T> LocatedRegister for T\n+impl<const SIZE: usize, T> LocatedRegister<Region<SIZE>> for T\n where\n     T: FixedRegister,\n {\n","prefixes":["v2","05/11"]}