From patchwork Thu Aug 29 21:14:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Frank Li X-Patchwork-Id: 13783882 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 27042CA0EC3 for ; Thu, 29 Aug 2024 21:15:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Cc:To:In-Reply-To: References:Message-Id:Subject:Date:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=N1/4E8eg5HJU9suKMORNq8cc01IjDNBxZ1KFxQ+nhPQ=; b=tI6O8O5oOQCGfVznUgTaduuTyn EvbAqYbiS8hjHxaYUcypaSMClFFZdlaCufju3slSGaXgVzcVQ5Jkyr/0rBzRuQCOwhyD1iOcPOaWM LQtYoATAmZMu/6SvF4VHAC2m6OChzdqTUDeXUFs8vamozmtTEZrE/8RldlRX4yGK+Ghzia6SqP8sc H+004YtMPIIEDN93kAkgghgs683TCTGpCnIyjpQUGgeKiAORrI03M0bfkfITKj7HOemkm45i/Mra7 2G1v0Q7Tnq8rz8x6KRLI74o4hHRKkbFYJpORXQBdHGntKXCIdAb9vj+7XhqVnkQUcUHTJ6gpbKxSJ I+fW3zeA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sjmTx-00000003eqg-2rP9; Thu, 29 Aug 2024 21:15:05 +0000 Received: from mail-northeuropeazlp170110001.outbound.protection.outlook.com ([2a01:111:f403:c200::1] helo=DB3PR0202CU003.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sjmTu-00000003en9-41ia for linux-i3c@lists.infradead.org; Thu, 29 Aug 2024 21:15:04 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=XWyZqWR/n+pCqmGpo1QwzXREaVS9Slf/BadmgHiyyBWfg8oWEj5u1bwhEvFEba/TEzE1cDTY7a8X9kdsdmQYhVBh46Hrb1caw7+xTtQRRfR3oNfKKHuoCtLrhG8ENR94ubDydkYJn48fiucTA9FJDfDTIoC6lVW33gJiTLZceENifbD7soAEpnIdLQ6dW27GgCA3arDxvIQ5F7obX7eSvXKsOCBUSj1gjedckwpft2Wb7mBi1EsLEf2VZD9Sof/3GzMfw1v/CQipN3RxNMtXI5fddNopF5tJUdZvEQsrGJqr2Qcwqpd9e8rvfse1bmoC5F8t2XBOX7zq8940FrI9xA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=TqVyPCbPTJ3sdEA/27481SZaESH46IwUHMWlvgoCoX0=; b=DExqCNgTS7YjaUgh6ZnJ+e3yo9HCvS+hNtv5CgaK6yV0KIdNXOf9HFoqwfWzQ1h2bTBNoUWvloSPHyMmRBZUmrkx2SjDHJ85hz/buK4MZle+wcgJ04nPsgcvNPHrt+cCCs6pmaVUAgcKfhcv9Oxi/IDEGPFEs5IcnoknvBGh3DtgC0CAabnsRhb4bRDdp1RZB6dIZmU4mg+0hb7/kOXhJiNHLrA3qfwze5Cu0YLYxg6q6HRhYDS9E21xpRHpjGeGSDdO9pfZnQAHZ6f6jHxgzzQ9HnuNQ04XzCvqztp0BIbRnIm/MxDS3CMsVgmoEkOLk7zUgKKp1OHeT9yOr7Vm1w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=TqVyPCbPTJ3sdEA/27481SZaESH46IwUHMWlvgoCoX0=; b=YoFSExIQDco130ynxt+gMFv2VSjM9Vfi6c9wbQA2+2Eai72+16S7LkCI6Kdw1kpL1NzqP+0xqeRH4ii8rnIJlmBT8kCVamyPOivFsXoSAC1zMul0VgrkhYnPKQonrCr1jsm3Hv9sJaTXJAv4Iu9orgIs3OcH7RgiW6N9YFyWt8kRmz1Vb7+h3ANbh2J1SQz/FYuDri6OA8nz6Zy8Nq/6zyw2SQa+p9AUECw201J8toQsykJDhtSiN8mbzlKIWeJLeU3eUykwOkfRouKWKMPg+5T86wdwRw285GiN46T6NDIJoCLFy1cLwoV+JCBXDmo5IfdlFwK0akcbO2+7HOHtMA== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from PAXPR04MB9642.eurprd04.prod.outlook.com (2603:10a6:102:240::14) by AS8PR04MB7560.eurprd04.prod.outlook.com (2603:10a6:20b:29d::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7897.28; Thu, 29 Aug 2024 21:14:56 +0000 Received: from PAXPR04MB9642.eurprd04.prod.outlook.com ([fe80::9126:a61e:341d:4b06]) by PAXPR04MB9642.eurprd04.prod.outlook.com ([fe80::9126:a61e:341d:4b06%4]) with mapi id 15.20.7897.027; Thu, 29 Aug 2024 21:14:56 +0000 From: Frank Li Date: Thu, 29 Aug 2024 17:14:00 -0400 Subject: [PATCH v4 03/11] i3c: master: Extend address status bit to 4 and add I3C_ADDR_SLOT_EXT_INIT Message-Id: <20240829-i3c_fix-v4-3-ebcbd5efceba@nxp.com> References: <20240829-i3c_fix-v4-0-ebcbd5efceba@nxp.com> In-Reply-To: <20240829-i3c_fix-v4-0-ebcbd5efceba@nxp.com> To: Alexandre Belloni , Boris Brezillon , Parshuram Thombare , Greg Kroah-Hartman , Boris Brezillon , Arnd Bergmann , Miquel Raynal , Conor Culhane Cc: linux-i3c@lists.infradead.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, Frank Li X-Mailer: b4 0.13-dev-e586c X-Developer-Signature: v=1; a=ed25519-sha256; t=1724966082; l=9448; i=Frank.Li@nxp.com; s=20240130; h=from:subject:message-id; bh=HWDamdLNANEwk6vCRoWBJpLPEb6ZbVWcj6qlnnkj070=; b=o0DTeRjMQ2dHAzjUlY0ZhP29WKNDnfr5q/pYpbfcM3XVaeFQCVQZm9JJ6DyOp4kOlPEjNdu2p VBYLZjNuE2lA5gtbes8bZXaeKOEK0cVKIcc8YyQkyKhjDP+auXwdBQZ X-Developer-Key: i=Frank.Li@nxp.com; a=ed25519; pk=I0L1sDUfPxpAkRvPKy7MdauTuSENRq+DnA+G4qcS94Q= X-ClientProxiedBy: SJ0PR13CA0219.namprd13.prod.outlook.com (2603:10b6:a03:2c1::14) To PAXPR04MB9642.eurprd04.prod.outlook.com (2603:10a6:102:240::14) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PAXPR04MB9642:EE_|AS8PR04MB7560:EE_ X-MS-Office365-Filtering-Correlation-Id: 8a45bccb-e3f9-46c2-7689-08dcc86fa1a7 X-LD-Processed: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635,ExtAddr X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|366016|376014|52116014|7416014|38350700014; X-Microsoft-Antispam-Message-Info: =?utf-8?q?99lcKMml1lEKRs9ZoSlw783+6SzBejz?= =?utf-8?q?GM+tWcg3ADksr87lDGKvFVrHV/uBCo53sOI/PHHfG+aCNxw/S8goa8yNT34YV3O2O?= =?utf-8?q?tdliLlHXDSF+uQmEbATZcBqevE3UWOZZhzpf0InWpkZpKmaxSTCPsvu22TJtt0kaW?= =?utf-8?q?qRgWbE9ZIWaVt9C8ZVu0+dHR1bYyvUNTE2YNwN/cHUzWUBx9LLlQGvJDV+Ra7R8rL?= =?utf-8?q?nu4bjVyV/envgAH66uRzq4CPd+jNfVOOQxh/AoXqHOpBSXhxY/em7o2dpwrRG3/9m?= =?utf-8?q?Yc2SknlbhL5WfOejC+choh3nN6jbPqgZkBatei2IsEthnApAsKWezy3oAuInCqlkB?= =?utf-8?q?NcFQOQbjbckA8rKfl9ba68ukcyiJt+i1WY9HS4B+jrZY3SCm/ijysQuCBCLNJ2jPF?= =?utf-8?q?a08Nd7vlM9adKdEnQ8iG9isXiErEz70KqXlpp0xOEmJ/ke69ajMBq/Mf8btoY8Qb4?= =?utf-8?q?PJbYPJsCAl6cm2ahf+mjiXD5SoqKsVo0GP9HjrgWYPD/VvfqSWKwgxeffeaPiDLEa?= =?utf-8?q?8iW57gb1H6UcwOadzhUE2v2y9VdohcwUXVajXV8+GoeRfmHr7PyoZGPL/3qViw/JX?= =?utf-8?q?Ip7/RPdqJEpiaskOg6mi9EbceZromfy7WtKA6DHZQGaSLNLOWqL0Vho6xfm6pMOaD?= =?utf-8?q?840JW+lQOGysP5RTh36Ow82Whf5UyhGHQfJ70/1/9qFhaNPS5Kf6kCBOalDJler/o?= =?utf-8?q?4iy94B37+7bCqwtrh+B+XKT6viO1AiIz4cA5SKkVnk5pmJ1LRfFdAsJqVU9WCXnPP?= =?utf-8?q?rY00c46IWNTBOcFXOHg0dKbUR1R0+CHJVQ/UnS9xd2YlS8X7P9lmqK4m797ig/X+0?= =?utf-8?q?/xeInli2alN37yvCldCH/7xAjSoMSQjA6egRdxXvUJeV4QUyojq8Yz0Hpt5BGz93g?= =?utf-8?q?3KKRHJxS5Hdv4j8LvsIbpvS3mv51Ft+bGy1YHx2nrTv9+lsMrkepGPcIzNyERLZY3?= =?utf-8?q?Ufb2LKkOUlz1TQY/UUyzY5W01w9Fh/G4Kd9kjJpGuLTg8aIDIpqIaHstIj4PlEDPW?= =?utf-8?q?HhoKYECSEqvbfUoAnjk8tz/yBqS6JjNtcscaNhjJ7z3stD6xRmdLmsjAPrA2EVxBt?= =?utf-8?q?RRibPnmlzecuZSV8PsJ9dGiOlPiDmm9ktT92ls8DAlsEgIMYutJ7IqxCwf7YntyKy?= =?utf-8?q?Axfqt4U5b++hUBCbjiRgNUcdfdGqT5niiHRvvItZSWG1Rkzlods5VD7jfUZQwSVoK?= =?utf-8?q?ZeL4EpFCX06CZawNsn7OROBa986n8HUgtU0exixM4/F9hohtkAxDQsKSF1AAHGUyo?= =?utf-8?q?iMG/KBr5/rsiLl5Ed148379HNcOFgM1z4nkTN2OddHrEvl5pwX8wXG6hkizOi6WBD?= =?utf-8?q?ynRNGI14KhNsLfni7+wZiOjsPEcwiLwwUQ=3D=3D?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PAXPR04MB9642.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(366016)(376014)(52116014)(7416014)(38350700014);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?dWcm4/IpkMXCWRghEUJD0dOyOHY6?= =?utf-8?q?j0XlYUfUFy94iWl6SNszOcIaXE6j0kPiTsHHvNUVG5Y87wW9IjhZOMwslPPI1b7SH?= =?utf-8?q?DZ3fcb8KS6s3z36jMaNNDZJnj2zwwym1+0N5MtYX6NLBPLnbQywKRa7bVziibhR6a?= =?utf-8?q?H0khES9zX43xK9hk9ERrf5vgce8ZRsV9wKzSPdlZD6QTPDScf9BC04Jcx54MZsB9W?= =?utf-8?q?hxcvZIGXxtYwjNQKRerl0Ie0CsH5IXh3jfYp7d/eFmR3CPCQ90B2QlM3C+XrspyCJ?= =?utf-8?q?yd/R1q78FPBWKbdJC8PxwUcYshTG0TYZThSusV1E9IiLWyTB3K1KgQ+vT2vrqq7GE?= =?utf-8?q?1eauVQyUIn1s2LvDL/2efLxiD8Q2AbEoQtLFMFuXcY68/N0yRHi3izlb0aBmvYC1j?= =?utf-8?q?7NFuqWKA+e/ZzRNKG51FaGRhrHQEIYZmHaytMihNjzEBjvFG06a7Ytib1x/q4mrCy?= =?utf-8?q?a0kyZGBXf8Vl6qlTpLKrhwVjshlzj1M1W+AIXsGqYMS62y3PIKO46u9GUalqs3YOT?= =?utf-8?q?tXV/URoxwmcrLOqNwv40yMXh/Eb+kAzcWZIk6ox30kr/9CHkn6o3Ghf41eqTwx0Oe?= =?utf-8?q?EEyUVK2nvqnn+2ElVx9kJ0MPdAELmN18IA+kwxr8XDpJBvZoCsqXrVyhyc3Fs/FSo?= =?utf-8?q?0k6r+ZRByeaFSotk4R4VRJzD5U3al7qT974Ni8jsEL23WY8n3p5p6Z3EUrizA1yiL?= =?utf-8?q?qcbF1duea9e/RPPH2qJ6cEGxAY5rgqW55jlCHavwKrHEuQHP+wJqt39eNufWDnTP/?= =?utf-8?q?djQZEaGBcfiFwxvomYfARu6EqUO9FeUNuBlGwlbZCqZ16OkKGQqmPH+khfWKnEj16?= =?utf-8?q?vQf18Dr3b9Y/yjhVSbxLhRVuJXoOtcnssO3zxAdAT0QZL2S70p5Mtwl+6r+2f2o7s?= =?utf-8?q?AHJXQLdLAtuDYRRPKkKb4fDieBv8MtiUjUB8w94IHTMmul21KYESFjrSA/aiBZeV6?= =?utf-8?q?gIBJk33H62rqH4MtcWDmogMgjUFDmXfDZbvOpEuW/gtW6NPZwYng64bQUtGY9ihYg?= =?utf-8?q?8EdhFN31L32aIksv61I0aYZMN7pneTeKo75kj5v9/p01tb/O0sg4ZDp2Z9Tc0V/mH?= =?utf-8?q?c6RtE+yoYX140Xnhay4pjGlEge1eD9XNzWAop8AsUaSStg9IUvAhHcWZ4MK9loShW?= =?utf-8?q?0IP7EP+OVu8a17KE/QG8MZXrH3zP3GXvu8vYtsMcm47VlJiatRgxrgiLjQVIPNEWr?= =?utf-8?q?JxZcRY7J0J4fi8DTverhKh60lkLAd5M3h/cmYH0spk5R+w1/r3gru3fdeBV3RTv4h?= =?utf-8?q?K4zfcKEWh9X+oWw7LAae9H/BQK2Y6Q9NbhiYQpdIMijnx/KzV3JrgB47Hi3foSPCV?= =?utf-8?q?YJFk4hClCE6inEFK5QK7xQOfJjjL1vvgMmxP0w7Dl2NUwsowyNDS8iiQw9kpmVQQ8?= =?utf-8?q?mz4zAefCIwOfsWUINRb2DvqUmk2DBVy2u3khuJTdEJrsHODCTIrBkPera6238/Ou6?= =?utf-8?q?TOKWcemaMn2kc1r7CtnFBE9TR7QRdcLheScbija8ajmuHDohBo1GMhUmtI/9lS65O?= =?utf-8?q?AnsT6dWKn3ej?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8a45bccb-e3f9-46c2-7689-08dcc86fa1a7 X-MS-Exchange-CrossTenant-AuthSource: PAXPR04MB9642.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Aug 2024 21:14:55.9928 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Mny6fsAQNVodahvUWN5sdpCFTNSygTUZS7xwupHNuElMyJTxJQ8OBqMhXLbHK+ERX4Te3rR+KFdLzV/IZ0HXcg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS8PR04MB7560 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240829_141503_044124_7613B52A X-CRM114-Status: GOOD ( 17.86 ) X-BeenThere: linux-i3c@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-i3c" Errors-To: linux-i3c-bounces+linux-i3c=archiver.kernel.org@lists.infradead.org Extend the address status bit to 4 and introduce the I3C_ADDR_SLOT_EXT_INIT macro to indicate that a device prefers a specific address. This is generally set by the 'assigned-address' in the device tree source (dts) file. ┌────┬─────────────┬───┬─────────┬───┐ │S/Sr│ 7'h7E RnW=0 │ACK│ ENTDAA │ T ├────┐ └────┴─────────────┴───┴─────────┴───┘ │ ┌─────────────────────────────────────────┘ │ ┌──┬─────────────┬───┬─────────────────┬────────────────┬───┬─────────┐ └─►│Sr│7'h7E RnW=1 │ACK│48bit UID BCR DCR│Assign 7bit Addr│PAR│ ACK/NACK│ └──┴─────────────┴───┴─────────────────┴────────────────┴───┴─────────┘ Some master controllers (such as HCI) need to prepare the entire above transaction before sending it out to the I3C bus. This means that a 7-bit dynamic address needs to be allocated before knowing the target device's UID information. However, some I3C targets want a specific address (called as "init_dyn_addr"), which is typically specified by the DT's assigned-address property. (Lower addresses have higher IBI priority, and the target can adjust this by using the assigned-address property if using DT). The function i3c_master_add_i3c_dev_locked() will switch to this "init_dyn_addr" if it is not in use. Therefore, i3c_bus_get_free_addr() should return a free address that has not been claimed by any target devices as "init_dyn_addr" (indicated by I3C_ADDR_SLOT_EXT_INIT). This allows the device with the "init_dyn_addr" to switch to its "init_dyn_addr" when it hot-joins the I3C bus. Otherwise, if the "init_dyn_addr" is already in use by another I3C device, the target device will not be able to switch to its desired address. If all of above address are already used, i3c_bus_get_free_addr() return one from the claimed as init_dyn_addr and free address slot. This ensures support devices as much as possible. Signed-off-by: Frank Li --- change from v3 to v4 - rewrite commit message and comment for i3c_bus_get_free_addr() --- drivers/i3c/master.c | 68 ++++++++++++++++++++++++++++++++++++++++------ include/linux/i3c/master.h | 7 +++-- 2 files changed, 64 insertions(+), 11 deletions(-) diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c index 2c9d45486ed8b..1dad727e28435 100644 --- a/drivers/i3c/master.c +++ b/drivers/i3c/master.c @@ -345,7 +345,7 @@ const struct bus_type i3c_bus_type = { EXPORT_SYMBOL_GPL(i3c_bus_type); static enum i3c_addr_slot_status -i3c_bus_get_addr_slot_status(struct i3c_bus *bus, u16 addr) +i3c_bus_get_addr_slot_status_ext(struct i3c_bus *bus, u16 addr) { unsigned long status; int bitpos = addr * I3C_ADDR_SLOT_STATUS_BITS; @@ -356,11 +356,17 @@ i3c_bus_get_addr_slot_status(struct i3c_bus *bus, u16 addr) status = bus->addrslots[bitpos / BITS_PER_LONG]; status >>= bitpos % BITS_PER_LONG; - return status & I3C_ADDR_SLOT_STATUS_MASK; + return status & I3C_ADDR_SLOT_EXT_STATUS_MASK; } -static void i3c_bus_set_addr_slot_status(struct i3c_bus *bus, u16 addr, - enum i3c_addr_slot_status status) +static enum i3c_addr_slot_status +i3c_bus_get_addr_slot_status(struct i3c_bus *bus, u16 addr) +{ + return i3c_bus_get_addr_slot_status_ext(bus, addr) & I3C_ADDR_SLOT_STATUS_MASK; +} + +static void i3c_bus_set_addr_slot_status_mask(struct i3c_bus *bus, u16 addr, + enum i3c_addr_slot_status status, int mask) { int bitpos = addr * I3C_ADDR_SLOT_STATUS_BITS; unsigned long *ptr; @@ -369,11 +375,22 @@ static void i3c_bus_set_addr_slot_status(struct i3c_bus *bus, u16 addr, return; ptr = bus->addrslots + (bitpos / BITS_PER_LONG); - *ptr &= ~((unsigned long)I3C_ADDR_SLOT_STATUS_MASK << - (bitpos % BITS_PER_LONG)); + *ptr &= ~((unsigned long)mask << (bitpos % BITS_PER_LONG)); *ptr |= (unsigned long)status << (bitpos % BITS_PER_LONG); } +static void i3c_bus_set_addr_slot_status(struct i3c_bus *bus, u16 addr, + enum i3c_addr_slot_status status) +{ + i3c_bus_set_addr_slot_status_mask(bus, addr, status, I3C_ADDR_SLOT_STATUS_MASK); +} + +static void i3c_bus_set_addr_slot_status_ext(struct i3c_bus *bus, u16 addr, + enum i3c_addr_slot_status status) +{ + i3c_bus_set_addr_slot_status_mask(bus, addr, status, I3C_ADDR_SLOT_EXT_STATUS_MASK); +} + static bool i3c_bus_dev_addr_is_avail(struct i3c_bus *bus, u8 addr) { enum i3c_addr_slot_status status; @@ -383,11 +400,44 @@ static bool i3c_bus_dev_addr_is_avail(struct i3c_bus *bus, u8 addr) return status == I3C_ADDR_SLOT_FREE; } +/* + * ┌────┬─────────────┬───┬─────────┬───┐ + * │S/Sr│ 7'h7E RnW=0 │ACK│ ENTDAA │ T ├────┐ + * └────┴─────────────┴───┴─────────┴───┘ │ + * ┌─────────────────────────────────────────┘ + * │ ┌──┬─────────────┬───┬─────────────────┬────────────────┬───┬─────────┐ + * └─►│Sr│7'h7E RnW=1 │ACK│48bit UID BCR DCR│Assign 7bit Addr│PAR│ ACK/NACK│ + * └──┴─────────────┴───┴─────────────────┴────────────────┴───┴─────────┘ + * Some master controllers (such as HCI) need to prepare the entire above transaction before + * sending it out to the I3C bus. This means that a 7-bit dynamic address needs to be allocated + * before knowing the target device's UID information. + * + * However, some I3C targets want a specific address (called as "init_dyn_addr"), which is + * typically specified by the DT's assigned-address property. (Lower addresses have higher IBI + * priority, and the target can adjust this by using the assigned-address property if using DT). + * The function i3c_master_add_i3c_dev_locked() will switch to this "init_dyn_addr" if it is not + * in use. + * + * Therefore, i3c_bus_get_free_addr() should return a free address that has not been claimed by any + * target devices as "init_dyn_addr". This allows the device with the "init_dyn_addr" to switch to + * its "init_dyn_addr" when it hot-joins the I3C bus. Otherwise, if the "init_dyn_addr" is already + * in use by another I3C device, the target device will not be able to switch to its desired + * address. + * + * If all of above address are already used, i3c_bus_get_free_addr() return one from the claimed as + * init_dyn_addr and free address slot. This ensures support devices as much as possible. + */ static int i3c_bus_get_free_addr(struct i3c_bus *bus, u8 start_addr) { enum i3c_addr_slot_status status; u8 addr; + for (addr = start_addr; addr < I3C_MAX_ADDR; addr++) { + status = i3c_bus_get_addr_slot_status_ext(bus, addr); + if (status == I3C_ADDR_SLOT_FREE) + return addr; + } + for (addr = start_addr; addr < I3C_MAX_ADDR; addr++) { status = i3c_bus_get_addr_slot_status(bus, addr); if (status == I3C_ADDR_SLOT_FREE) @@ -1906,9 +1956,9 @@ static int i3c_master_bus_init(struct i3c_master_controller *master) goto err_rstdaa; } - i3c_bus_set_addr_slot_status(&master->bus, - i3cboardinfo->init_dyn_addr, - I3C_ADDR_SLOT_I3C_DEV); + i3c_bus_set_addr_slot_status_ext(&master->bus, + i3cboardinfo->init_dyn_addr, + I3C_ADDR_SLOT_I3C_DEV | I3C_ADDR_SLOT_EXT_INIT); /* * Only try to create/attach devices that have a static diff --git a/include/linux/i3c/master.h b/include/linux/i3c/master.h index 2fac4a45ec600..2c826d17eb571 100644 --- a/include/linux/i3c/master.h +++ b/include/linux/i3c/master.h @@ -284,7 +284,8 @@ enum i3c_bus_mode { * @I3C_ADDR_SLOT_I2C_DEV: address is assigned to an I2C device * @I3C_ADDR_SLOT_I3C_DEV: address is assigned to an I3C device * @I3C_ADDR_SLOT_STATUS_MASK: address slot mask - * + * @I3C_ADDR_SLOT_EXT_INIT: the bitmask represents addresses that are preferred by some devices, + * such as the "assigned-address" property in a device tree source (DTS). * On an I3C bus, addresses are assigned dynamically, and we need to know which * addresses are free to use and which ones are already assigned. * @@ -297,9 +298,11 @@ enum i3c_addr_slot_status { I3C_ADDR_SLOT_I2C_DEV, I3C_ADDR_SLOT_I3C_DEV, I3C_ADDR_SLOT_STATUS_MASK = 3, + I3C_ADDR_SLOT_EXT_STATUS_MASK = 7, + I3C_ADDR_SLOT_EXT_INIT = BIT(2), }; -#define I3C_ADDR_SLOT_STATUS_BITS 2 +#define I3C_ADDR_SLOT_STATUS_BITS 4 /** * struct i3c_bus - I3C bus object