From patchwork Tue Sep 5 21:38:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Frank Li X-Patchwork-Id: 13375083 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 76FE1CA1010 for ; Tue, 5 Sep 2023 21:39:15 +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:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=vfhYw0ezU+WdeSTfPY/qVbltlTxBbCvq66oNFO9LHDg=; b=K4lUZF/+4AvDaH THs4m1yLpcEihPaGmtB5MnoaAg6M9p8kB85zl8AWNY2wvgJ+MxYVt5xUuP9r1LhefrMubt+b9Ezfv amMJAzV7QEXMTlz+f/qil32Hs43JsEbmi3zw+fj+1NQlrEeE6xIDDWp+cOLkAWpCUTzEUsoRFBJ6c HovctQbGodo1juVGPDnwRufKf+AadM99UFRGqVpaLmGAXEoYjLph86Womw48PkZaG2AZaUsov2eCQ Tck0/HdFEV5JZUE5YtEJnDIM2XPATJjI8kqR83wcD8ulUzw/bVnjkvQnYZGUmEf7xxRVTUoIjzp++ 6ylraj5njGSKxxp7CryA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qddlS-006lhu-2v; Tue, 05 Sep 2023 21:39:14 +0000 Received: from mail-db3eur04on061b.outbound.protection.outlook.com ([2a01:111:f400:fe0c::61b] helo=EUR04-DB3-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qddlQ-006lfI-2E for linux-i3c@lists.infradead.org; Tue, 05 Sep 2023 21:39:13 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=hFnjv4rH/R/nAYzObyQpnij0UjAhLbviyhlErAh5BVaL4Dd1+DKS6SQGfViiOmPjtiv5En2IAqePu/WTAFE2bGnglcVPDDORAxK5aQYhaPW1ULUTI4UTe/PkvsycpOg/iGJiaLeZyhkEPAm9+g0Iwq22Xwsg7sBRX52cTz0Z2tmUee3jnxspyeIAaCEa6SYcCnyR3GmC7kEvNxK2AyrJnqnk/njkaLn71L37yGDX3ymnbMuDRqmKM4vTlpTaYNvXj0J8x8O2ABlnz2msBzX/By/WPA+AmKEfzNHs2BwHS9yeoV2Sb/kwLV3fPOBhymAvYQQUvEWfzVNceqfjkph6EQ== 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=GjL4OHwC/rHtCDoRpljh9fgGCzjlUSYpZKXCcvdcfOA=; b=MpeobatYKM0tsI7c9FhcQlbfQ0zStmCaDYnLvOT6RQxQdpobpcsF7sDYv40/kaFZkGwTYrAW6gFpl8CKrv/VBTEQy7UcWV06PKmKQcigjnh5kxs9+Aby3t+QLsaR3D7ySYFG0ptFCDNpni1mB1mmrKZDJAUDI6EzvuWNaFVI4yVrKX2DMgBux1+uwL78rBmU5vrS06QH7lAwV5nArtK5ZpZgmK/d6egqKhGYxhq04lzorl+PhrswR1/aeW5VlhopDlHLRW1CQxvhX0xPCcnZjzO1/L+kUJj48g0k8ILVCHhdFUPyMukl7H8DHB2GRAqsOP88sik0dgfx6zbKMgwjaw== 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=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=GjL4OHwC/rHtCDoRpljh9fgGCzjlUSYpZKXCcvdcfOA=; b=Dnz3e+CrQov2AJowNWT26JlTi2ECBhxdlnHhzbD1KWUPgQ5HuYLxJ+zybdI1dVrW+ae6HqHli2+lEoPK0dFWQRHFZNZMjy5gCVpBy0XGwF7kw/zuRDQaTvUXGhL0RE72lYtNlD5Fu5/IJzg1m1XhwKZzyxi69l7gsHewcdpqAOk= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from AM6PR04MB4838.eurprd04.prod.outlook.com (2603:10a6:20b:4::16) by PAXPR04MB9256.eurprd04.prod.outlook.com (2603:10a6:102:2ba::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6745.34; Tue, 5 Sep 2023 21:39:03 +0000 Received: from AM6PR04MB4838.eurprd04.prod.outlook.com ([fe80::aa90:117d:c1d0:346a]) by AM6PR04MB4838.eurprd04.prod.outlook.com ([fe80::aa90:117d:c1d0:346a%3]) with mapi id 15.20.6745.030; Tue, 5 Sep 2023 21:39:03 +0000 From: Frank Li To: miquel.raynal@bootlin.com Cc: Frank.Li@nxp.com, alexandre.belloni@bootlin.com, conor.culhane@silvaco.com, imx@lists.linux.dev, linux-i3c@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 1/9] i3c: add actual in i3c_priv_xfer Date: Tue, 5 Sep 2023 17:38:34 -0400 Message-Id: <20230905213842.3035779-2-Frank.Li@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230905213842.3035779-1-Frank.Li@nxp.com> References: <20230905213842.3035779-1-Frank.Li@nxp.com> X-ClientProxiedBy: SJ0PR03CA0215.namprd03.prod.outlook.com (2603:10b6:a03:39f::10) To AM6PR04MB4838.eurprd04.prod.outlook.com (2603:10a6:20b:4::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AM6PR04MB4838:EE_|PAXPR04MB9256:EE_ X-MS-Office365-Filtering-Correlation-Id: 8ee94220-a981-48b6-5114-08dbae5885db X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 7KBbxbE8CGm5YJ4Z6TgLh6Y5WZtxb2/qdL5p+kWerzMP9m0rIpbX1up7LVMGiMuAsLuXkAMFQ2jWR/nk7J/Ti9lbCcx4Bi0/0E5P47eBXLToiKw1YStrB/Kg0Xi3x/XjElQw0xYFNPpdCMlZ1DiXWhFXV008r+ibVPNktenq6ldaHJZlGyrDHyzv5VyrZVUA3Q0nJXqFAjgoFNegkfL2cPqxLuTlwH2q9tH0Mgn3i3t6IptrdwySMMFUt44yHS9AQcj4Ne/Z09upKAZRCy7UBiyfrJ8k/YNN9RPIUvGAg4HU56oBs6OJC2JW711PnZFyBAIcYKofnVLmlwtnRVgRjprPvv2+bDRqPs0dqx91hUT9xWEzq6rPxrNtxZBBDKJzVX5V2hEFMFGzcAN2ujeHYLbqH05X97lp+4/gtGkfaX1uHZGlZeVrvI8AeAfTLSeoCtkbQk/s9xi+dnyB45ILZiiL6PRqGSjZrrxgixgC8RU0VH6zrBahmyupqC9Y+4PGKzFLg0eMUslMT6PaYZVV0VxqRwEE3pnZoJWmnak9/JdiUatmFXA3RkepKZ4dSo918ql8JQwPlQUGRGbas17AruXOv7c3CUsohKh10ium/qy6wQlm3uag3/1TrWor6NdO X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:AM6PR04MB4838.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(396003)(376002)(39860400002)(366004)(346002)(136003)(186009)(1800799009)(451199024)(2906002)(4744005)(6486002)(52116002)(6506007)(6916009)(316002)(66946007)(66556008)(66476007)(478600001)(26005)(6666004)(5660300002)(1076003)(41300700001)(8676002)(8936002)(6512007)(2616005)(4326008)(36756003)(38100700002)(38350700002)(86362001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?E5R14z7/342ycJoMVymdOOxgsxWm?= =?utf-8?q?NiPj15TIdZrLk7qf+88OLmrFSsNmMPB1x55khNSeIyLSvelAlhwR0Gt0USHOiHH0y?= =?utf-8?q?eypToPJsnbB6escyugrI0Jh/MphRQruutn65mgLwm5Lj3aS5j8cVXh+TMHvEqPAzU?= =?utf-8?q?AP7rVp80/wb0ULw2weL3VPOY6XE1BHLie2AM65/Q/BRR3fyPf0hF9b6fnE0jcA1xO?= =?utf-8?q?P2r138ev0XDvpy5TUHxBqrJokd91JP5BM9F89Rkc1AlrA1hjxfjiMRbRNWszc+2Gy?= =?utf-8?q?tnXCnmfUf5VOrNx3yypaP8iJ9trhT3vK++Y5kkrDN4wNaRM9M/RG5UuMhfR6o1wSv?= =?utf-8?q?kq4oNfzRklmyCEu5FfUqioGHM9l0R7ZZT/LDBbzuLOQ0IjW2U47/i6pKXwg+57P1y?= =?utf-8?q?567ITQh/JWr/BF618v1JvyHOY8uEbCofn5QdI2UEU6khNHAbyauOkAj2im9q/JGfx?= =?utf-8?q?yDFTfLjgmR5b68KolZohT0GW0DstaDYzpp7sy6CneGorp8NmlNsPjt0HXgHuvbJgD?= =?utf-8?q?Szw7OdgOHln8w4VYqoJOMTHBZsAvkkNDJO28iN7Gx+pTot7E1lEhdTpiv9TecGTN6?= =?utf-8?q?1HgEVvNnXsRxfmdkWhKOQ4jkOqZwYNZUYiFL5WACguWAE5xgTMopqwhRwqwyVQKZ2?= =?utf-8?q?oEZZudReouYb2h+n2t3fMZb0p9LyFLhBNJ+Ueq1xacY6h/auw7LuGR3zb0HHmFX6E?= =?utf-8?q?k80fJ/jErEPEBcAy4qOFkO8E7J764tn3GPK2COUk6/x+0HeWPNOHQ/qGOdK/mN1zB?= =?utf-8?q?n0vlXwcR0UbKidO+ui6mwifCXbW71TrBWT+Bb0QoyI9DxlPa1bcH4h3t1FLA8cPyT?= =?utf-8?q?oLGUVa3fNW1pwFbvtef9qyp3QRRt2oKajojuszytOkwr0FrkCIy20vY2CBpWfP+X8?= =?utf-8?q?pNnxvtcfYpd+eLNApI4x0wluYucwIjXMIeLpul5aL+sqcnYgzE3qZbdzHahWCZDsf?= =?utf-8?q?0iWP9hCI6tutRJBwBUlk73SrfLREYzJ2Cbbr2tWGdMOMIOXKzwJw3IRtY+VHvmRCX?= =?utf-8?q?d+MKx/O2HTt+RzqCB+jAyaD00WyO/ikH0R+bZafuk7HWtgRXOpti3kIs0ig6GyUqv?= =?utf-8?q?hU1LG8J66jHay7I043n6giW43TSHxM367JPtmJJ1QgJhbhLulK49iHuYmKc9dICT6?= =?utf-8?q?1+XZOHTSqnXCi2lmK3tCng2lMJ6fJVcnZPp6lB8mxupxI/3AUjqvKtRKu2eNYQ43I?= =?utf-8?q?kHTHgVPucUN7nlUx80e5gSEAahVIkV97zPYwiIOdhAP/QXKap9uSrVR3l3UYZK6QU?= =?utf-8?q?6welzdcRWhscnPjZBzWC1zgVijBmo0kzq6ccGf+OLMv3cyOpKMtNr7sGRUsGXP/wQ?= =?utf-8?q?Nyk4Wuv81pjfILZLkPWI1zLyBF6AD7tBysAhpxiUVCNx8sf8yy24Qe6wb8hQNEXvc?= =?utf-8?q?X+WOgzaIQY/ORcDp5WzG9ZW5ObjRffv37Hq3PDZ39oS3l2wO8MGdQB4fUZR1GK9sQ?= =?utf-8?q?BF4Aa2fJ5sYdtZhemMOhe/+555axoZSACOTRnQVHyUepWLElRGRgyhqo3ttovXG/N?= =?utf-8?q?srsxsLAPikGA?= X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8ee94220-a981-48b6-5114-08dbae5885db X-MS-Exchange-CrossTenant-AuthSource: AM6PR04MB4838.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Sep 2023 21:39:03.2214 (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: 7vn5NFJ3gXc4rvsmqLRevuRUGCEmfus8JB9ph/3kN1junEHj7dN6gmArrHo7PkussjFGspV74y7XCJRWOIC4nA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB9256 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230905_143912_731718_95EFD63A X-CRM114-Status: UNSURE ( 9.88 ) X-CRM114-Notice: Please train this message. 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 In MIPI I3C Specification: "Ninth Bit of SDR Target Returned (Read) Data as End-of-Data: In I2C, the ninth Data bit from Target to Controller is an ACK by the Controller. By contrast, in I3C this bit allows the Target to end a Read, and allows the Controller to Abort a Read. In SDR terms, the ninth bit of Read data is referred to as the T-Bit (for ‘Transition’)" I3C allow devices early terminate data transfer. So need "actual" field to indicate how much get by i3c_priv_xfer. Signed-off-by: Frank Li --- include/linux/i3c/device.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/i3c/device.h b/include/linux/i3c/device.h index 90fa83464f003..f2fa7ee5d96d9 100644 --- a/include/linux/i3c/device.h +++ b/include/linux/i3c/device.h @@ -66,6 +66,7 @@ struct i3c_priv_xfer { void *in; const void *out; } data; + u16 actual; enum i3c_error_code err; }; From patchwork Tue Sep 5 21:38:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Li X-Patchwork-Id: 13375084 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 A2724CA1011 for ; Tue, 5 Sep 2023 21:39:17 +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:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=6fpMwEEl2LMfG9mHTirvEfc8ty3TbdHV+WxFHQGdY6I=; b=E8dp+7CvOpTW82 d9fWkJUODFINfdlw0r6f6uueuchN+LB5X5vQNYJGLNaJwXWFA100Rw6pF0hrQatWPsy2t4nWxLZYF KritAqS03/O6t8pLjt9rxJLPalpbPg2VlpG6XW46L37wK0mAAnmgRovO2QRjmIQ5QgMfuaAbyr/Kb xMiuXu2ER7EDkeosQp3baNXtAHJMBeyi5gG6SVaHdyGPJWdSV4xYJGnEibGNc7n+AoqAYfG1EXVC3 aKUnerGWtL5OkeFw86cBSFP4EtWzbgVRaztNH+RlMdepeor3bUwyCK6BPR5IsZan5ksa43X0gjpxD nvhe+UDQ3bsBKkVWnrMg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qddlV-006lj1-0v; Tue, 05 Sep 2023 21:39:17 +0000 Received: from mail-db3eur04on061b.outbound.protection.outlook.com ([2a01:111:f400:fe0c::61b] helo=EUR04-DB3-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qddlS-006lfI-0X for linux-i3c@lists.infradead.org; Tue, 05 Sep 2023 21:39:15 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=KjRkvqMjIyAo8bDace0a76AHOJLB39o5DaaZOtolfsxcZ14tFWf/Ypl2EiM4aGJu63kvr2PsTwRnEsTvMnoQ6st5v1Wr73KhRD/M83u1sdl1pjD57G43UpowHsP+xAO4YNf77Gh+R4FDD0xvdp8sh+OmQsRKGaIsRJCrx+Du0k1a+uLllehn0dJC95+XI7c7KutOr8HgQtOBBQLgeDLiLv6n5iup5TTbqKUtVEpll5pzEEv3tXMfYrK8C5CxWY8pQLNk1DWF5yVL+zrlYE4KcRIc0GpuDlH/BG7/UEcaPb2vdJS4RSBZmDFWS4WtvgAcGSxfYCYIj9wx4c0n8ddqUQ== 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=4Gz6GFr5dSdKV1RrerMs7k1IQ4bqOyJkUlukRjdjics=; b=hF6NnpTQolxe+TVk8iX1KKyMyUWLZ5G3hssv8E1g93pIcHev5Anyv599G4QHmC7985irpJi0sbqYoS5RRrkh9VekziDyFAmE/royEpJDwvuefHZW41J/yP4MZ2i+dRlU5V8n2sPsiyzlLnSW7SH0NxxfIUMp/e+hc6f00GCyzEt+XMrPRtyBwraCELHZppaLRnBihxfbyvU4J/MqZE8KbpIY9p0KuwxTQ6WsJX+TTHz6TeuL3iea+HXZtlaVNQpUZY6Sl+mP57WsMrFt80RhOuSNw2QLrYzdbWHVbqBE44MaoV0WYXulbZgpH42QzcmWjvnHWmf8ZHoCsgFO1YifbQ== 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=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=4Gz6GFr5dSdKV1RrerMs7k1IQ4bqOyJkUlukRjdjics=; b=USp6DRQoZgTEPKjlqiHUlEsavv7dIhwUfmFrf1MYps+p51WgpEEwDno57ZnBrl1vN7l3EezVesFDOm7ByzpuXpjf5UeWRzKlBlBd8sUywan+/HcF0jPEM7jMGhvio+qe/hZeY89ABOCS815pCDX4/j474cequ0LdquRGdLMnod4= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from AM6PR04MB4838.eurprd04.prod.outlook.com (2603:10a6:20b:4::16) by PAXPR04MB9256.eurprd04.prod.outlook.com (2603:10a6:102:2ba::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6745.34; Tue, 5 Sep 2023 21:39:05 +0000 Received: from AM6PR04MB4838.eurprd04.prod.outlook.com ([fe80::aa90:117d:c1d0:346a]) by AM6PR04MB4838.eurprd04.prod.outlook.com ([fe80::aa90:117d:c1d0:346a%3]) with mapi id 15.20.6745.030; Tue, 5 Sep 2023 21:39:05 +0000 From: Frank Li To: miquel.raynal@bootlin.com Cc: Frank.Li@nxp.com, alexandre.belloni@bootlin.com, conor.culhane@silvaco.com, imx@lists.linux.dev, linux-i3c@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 2/9] i3c: svc: rename read_len as actual_len Date: Tue, 5 Sep 2023 17:38:35 -0400 Message-Id: <20230905213842.3035779-3-Frank.Li@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230905213842.3035779-1-Frank.Li@nxp.com> References: <20230905213842.3035779-1-Frank.Li@nxp.com> X-ClientProxiedBy: SJ0PR03CA0215.namprd03.prod.outlook.com (2603:10b6:a03:39f::10) To AM6PR04MB4838.eurprd04.prod.outlook.com (2603:10a6:20b:4::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AM6PR04MB4838:EE_|PAXPR04MB9256:EE_ X-MS-Office365-Filtering-Correlation-Id: 20dcb33f-345b-4fae-c475-08dbae588739 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: nuTtVyBjgVHmt/styeByVSsUiPsatE08RlzeCM78tWvUDYDn0qYBDl40VDZMuEMz4nkCESkvJnUoZbGQ/M3XLnjOb0ZtqCpINEdOXC5i7Vzk4XODSaRzdP0nK2SQ4KoYO0P7B692Z9XJc57Qeu3YyptaVK5kriyL+9oPP0HJXxpSqNjs3aMiFKd9C3IN6WjvT7hkI/7cejKKrZzy2aAlkQy9iir2dFtOozVZEcVaY1RJtD+53PojopRIjkXPIlNIoytUyO2Ar8WPzIUpAVA1M6J4WsYJXHv/m6POltd9LG8xdqYV7/yyEX+K3pNiGWRRxWHCkgyrH8VCslTxL9a9okrq6G2xjhvcohi88IxoVGmr2DSKeQCj6gdTVNeNLnXGrU0d2IXII+fC5r0W4wLK/rxqeEIWa52jaFLlkCfSYpjxn7K8lbum3sWFQKdWdmNApggx4BbZiJ+RfM0LTd0PmsT3JWaIu/ZR8AVaDdlgrp7o89UJu8+6/PN8pR4kpzEPuLiasHl3YAEyc5S0nskTh4pf/F+xK9w0xmeDnDFPrtDxHbKsEHQxXA0e3cHzeN6m1IkLPEN3FCtFkAc+sLjz5eKdpjCNi3aPg7zKER7SRp1cv+PGL39Y9VzD12Cnv0Oy X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:AM6PR04MB4838.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(396003)(376002)(39860400002)(366004)(346002)(136003)(186009)(1800799009)(451199024)(2906002)(83380400001)(6486002)(52116002)(6506007)(6916009)(316002)(66946007)(66556008)(66476007)(478600001)(26005)(6666004)(5660300002)(1076003)(41300700001)(8676002)(8936002)(6512007)(2616005)(4326008)(36756003)(38100700002)(38350700002)(86362001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: MeCmOOB5gt27zTaghh8iJWXsrj4PMoTWh64TJP0rFlInHrPO+iK/GW6ScboiX+4E1FyKQKLbRA3jMg0yaYFRZH5aIPgB4Z3NutFqG/Rz1KzS0KAU+UVvTR7Uccr3xe5UTgGZgBZBVroAwxAnYNZ/oaFbSoL+HFTxK4lWoh4Bxk0OzH5La2BTWq/tQh7jRE0KsISxfgVRclzbDJTf+uTvPEim9gxUp/Z+immJ97fgOx298PtrMu9GQQrwuRvizvPRLhf3jFiPnAOw6WD43K3KZw+sOBw+eO8fCCwLfgyHIsLRYmA0ZRyGOVKio33bhQpDTYaTb8qnZgWz/W0OGPgk+oPEboGR+wTfyO+AO/duhBofTXQ5dTRopSFg7B/S1dia2uLE1+Wb3q9DmZ8gzlPCE/a0IDTPlKrirWbeSFcdjUrS1VurPzVuPO/XcVdkOdWmBmLhUxVMgtrrfGzyNf76NiGoPvn0q1f69JKkFwiZlbV03GlFkHHhFdILN4iS5rYas6zQ4ADJwHh4D7fDoONFCrEMGZDUL3/IJ2zIIm2BDQUVxcQ3VWazHbzyl9h3ng0Q2K+qHJ15Pi41vMr5bulvSmc9UXMVkUqO4jajoVHLIO/fz0DToQi6zKXucpq1Pue6EPKeY9hqeNvyULFpttlGAdCfSNGx5bE66e6Bh6U8Ir+97x3q14k6wmBlGU6gf4HFOwY8Kz/6oF62JOf/YYGkgdfg1tDNwAQwuuW7Dut7T46Ma0VeQL5Gg7wFbxpkuva1HOA9GhjGWIhT+t0VJXtCjULpdCsAjI6iL9bkuzuTTLkbTskiVnoyGyq3hsc1Le1eonR5Qo/yRkdQNy1mwh9Yto4Kch3qVd/t/8ITtaaOuMcmkYOsiCb9l2OQxJEu6It2AgHxRBROaf7da2K9kBtIr7loDKQtqIHpjvXRbrp9+UJVruzkognENBxpSXyPZfHN0zD4xfXa0H+I2INjvc3/BuqAb34mh1L1cuhTAQXYHjQ39e6xmEyc/iLyQlShLyuzqqFJQl/vphZkb9jM5IWJFZqORPT2a6ibfVqxvmxVmtH+J/psBewZlT/Fzpkg3XcQ7jbEJgdnQWfkRRtwm9OrZzzmZpz2bczekLA6lh10aDjrnWeGamZAtymYOaSHLEOawImpCmEv/2OjQTKcK+PYsTZf7bBVNJXK5W3mGfQ7U1gr44SIPeFgJcJShI69iHfVHr7xjk0DM31jfwTUobafBmxkToDaIXu3yXnoFgtB4sdpniSm/lspbO7DeKMBQTxHqFmyU+OwfvWu6tj6JIBjg0wRVBPFWn0UF64RExWBauFvzjfqLsTIKgFHFowh3HAWhm5xycaU/c+9G14QoUI6piliHqtAKJSVRRfrcSeKuG+pWAMNp598F8Pw80hUuMdrq0L196fpEvRc2HIEnox/tCEWPDhTGqibGCs4jNoxkjRz6QP7Nqdtryo4qvt0O8jMrJICazvidMVp0rWg5rGqTsYRpM+e8uqxCXVNxXq3gRa4/e9pe42GW/fmygS0WVdoJ1j2g2m1e3m1T25NQ/AdY2uWZnZvnmGU5YDXgcE4fO2hDdEn30Zk1dfL9V0emTto X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 20dcb33f-345b-4fae-c475-08dbae588739 X-MS-Exchange-CrossTenant-AuthSource: AM6PR04MB4838.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Sep 2023 21:39:05.3526 (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: OQWy1bP87XjKqn7LpradKg5VOT2jIN9n16/KGre27sC9SQW1q/3lNrw8Nc0i1N2kXWtUQFIoQvD3yjP37ACInw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB9256 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230905_143914_206957_BB8DCCC8 X-CRM114-Status: GOOD ( 12.02 ) 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 Device may NACK data transfer because FIFO full. Master side need know how much already transferred. Driver can reuse variable 'read_len', so rename it to void confuse. Signed-off-by: Frank Li --- drivers/i3c/master/svc-i3c-master.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c index c308e22f0ac5e..14185ee7dd19b 100644 --- a/drivers/i3c/master/svc-i3c-master.c +++ b/drivers/i3c/master/svc-i3c-master.c @@ -133,7 +133,7 @@ struct svc_i3c_cmd { u8 *in; const void *out; unsigned int len; - unsigned int read_len; + unsigned int actual_len; bool continued; }; @@ -1001,7 +1001,7 @@ static int svc_i3c_master_write(struct svc_i3c_master *master, static int svc_i3c_master_xfer(struct svc_i3c_master *master, bool rnw, unsigned int xfer_type, u8 addr, u8 *in, const u8 *out, unsigned int xfer_len, - unsigned int *read_len, bool continued) + unsigned int *actual_len, bool continued) { u32 reg; int ret; @@ -1011,7 +1011,7 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master, SVC_I3C_MCTRL_IBIRESP_NACK | SVC_I3C_MCTRL_DIR(rnw) | SVC_I3C_MCTRL_ADDR(addr) | - SVC_I3C_MCTRL_RDTERM(*read_len), + SVC_I3C_MCTRL_RDTERM(*actual_len), master->regs + SVC_I3C_MCTRL); ret = readl_poll_timeout(master->regs + SVC_I3C_MSTATUS, reg, @@ -1032,7 +1032,7 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master, goto emit_stop; if (rnw) - *read_len = ret; + *actual_len = ret; ret = readl_poll_timeout(master->regs + SVC_I3C_MSTATUS, reg, SVC_I3C_MSTATUS_COMPLETE(reg), 0, 1000); @@ -1114,7 +1114,7 @@ static void svc_i3c_master_start_xfer_locked(struct svc_i3c_master *master) ret = svc_i3c_master_xfer(master, cmd->rnw, xfer->type, cmd->addr, cmd->in, cmd->out, - cmd->len, &cmd->read_len, + cmd->len, &cmd->actual_len, cmd->continued); if (ret) break; @@ -1200,7 +1200,7 @@ static int svc_i3c_master_send_bdcast_ccc_cmd(struct svc_i3c_master *master, cmd->in = NULL; cmd->out = buf; cmd->len = xfer_len; - cmd->read_len = 0; + cmd->actual_len = 0; cmd->continued = false; svc_i3c_master_enqueue_xfer(master, xfer); @@ -1218,7 +1218,7 @@ static int svc_i3c_master_send_direct_ccc_cmd(struct svc_i3c_master *master, struct i3c_ccc_cmd *ccc) { unsigned int xfer_len = ccc->dests[0].payload.len; - unsigned int read_len = ccc->rnw ? xfer_len : 0; + unsigned int actual_len = ccc->rnw ? xfer_len : 0; struct svc_i3c_xfer *xfer; struct svc_i3c_cmd *cmd; int ret; @@ -1236,7 +1236,7 @@ static int svc_i3c_master_send_direct_ccc_cmd(struct svc_i3c_master *master, cmd->in = NULL; cmd->out = &ccc->id; cmd->len = 1; - cmd->read_len = 0; + cmd->actual_len = 0; cmd->continued = true; /* Directed message */ @@ -1246,15 +1246,15 @@ static int svc_i3c_master_send_direct_ccc_cmd(struct svc_i3c_master *master, cmd->in = ccc->rnw ? ccc->dests[0].payload.data : NULL; cmd->out = ccc->rnw ? NULL : ccc->dests[0].payload.data, cmd->len = xfer_len; - cmd->read_len = read_len; + cmd->actual_len = actual_len; cmd->continued = false; svc_i3c_master_enqueue_xfer(master, xfer); if (!wait_for_completion_timeout(&xfer->comp, msecs_to_jiffies(1000))) svc_i3c_master_dequeue_xfer(master, xfer); - if (cmd->read_len != xfer_len) - ccc->dests[0].payload.len = cmd->read_len; + if (cmd->actual_len != xfer_len) + ccc->dests[0].payload.len = cmd->actual_len; ret = xfer->ret; svc_i3c_master_free_xfer(xfer); @@ -1304,7 +1304,7 @@ static int svc_i3c_master_priv_xfers(struct i3c_dev_desc *dev, cmd->in = xfers[i].rnw ? xfers[i].data.in : NULL; cmd->out = xfers[i].rnw ? NULL : xfers[i].data.out; cmd->len = xfers[i].len; - cmd->read_len = xfers[i].rnw ? xfers[i].len : 0; + cmd->actual_len = xfers[i].rnw ? xfers[i].len : 0; cmd->continued = (i + 1) < nxfers; } @@ -1342,7 +1342,7 @@ static int svc_i3c_master_i2c_xfers(struct i2c_dev_desc *dev, cmd->in = cmd->rnw ? xfers[i].buf : NULL; cmd->out = cmd->rnw ? NULL : xfers[i].buf; cmd->len = xfers[i].len; - cmd->read_len = cmd->rnw ? xfers[i].len : 0; + cmd->actual_len = cmd->rnw ? xfers[i].len : 0; cmd->continued = (i + 1 < nxfers); } From patchwork Tue Sep 5 21:38:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Li X-Patchwork-Id: 13375085 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 4FD25CA100D for ; Tue, 5 Sep 2023 21:39:18 +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:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=C3itx87nHJ/tsuizoTxEmqiqAWO5Tg5x7tkIrZ5mZIY=; b=GURPeWkaqRFPbG rpcyZ4luP2qOtP8yYbHsPbFcPe70G28NgD+6RSsdzlTL0IpzNkoIR7mbGirJiZ4HD/1Zz3MqBGm6l Eem11v2GYKV+YY0CH8CVbVnv4P52nBP/ZYxNv5GN2S/fHDbEKIRfVUUZGrk/DoI98Kzlr3usIkaXx MbVt4kAQxCYE01PL1lwD/VsZpFtO75OwJoDRyNjiul8XmL+y/slj7vLk0N4N2Ni85WWetwtu6K37H y7Ytw7xVSXAZPfFUeMR8ubSbyeRGSsR3IkUUw6OrIQVArNS1aaYxwrVpuLOuPn47Rt/4lOmuPAx5T 34+uKsRytV/CJAhG+RkA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qddlV-006ljY-2u; Tue, 05 Sep 2023 21:39:17 +0000 Received: from mail-db3eur04on061b.outbound.protection.outlook.com ([2a01:111:f400:fe0c::61b] helo=EUR04-DB3-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qddlT-006lfI-2n for linux-i3c@lists.infradead.org; Tue, 05 Sep 2023 21:39:17 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=nZLQ2oq8vUkBRQCXKbltWIOTXDjOZLiRi4eiTe1lC7kNfQtGUiQ3ub5SHA8kDtrvYyshVvnW+id+X3CPIooh5y9Ho4e2gM+CoIPpvMxUarspYTlEC859zuexLHfj46MdwxcF0NZoOIyasNzn/3hAIfauvGIUua7EJdhoyyDS6Z5zv0DRvvBAF7FSQaxmXtewkkx9pD7aFyfLblA4PDT1Ha1fy/4iSu6imhvHXfwMDSevK8CtDyyQ3gNW6NljdvKQ5x/sef/anGBkjzgUItG9uLnfZdb7Rw7DtI0T9ZFk9n1Ibs3gM38uhHPrhRT/NSjsfPaUhNRcv1b5dXQ26R+FzQ== 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=KXqM//NQ+ysAHEKZp2WurCborK3eF6VEZ1fJI6P1LIA=; b=WOVlc8h4oJdMdcM9eL4piR3rSWvfeAU9qB90iiS1mXqtHMqCZT1tkOFIejsiOS0ctWS3cnovN++5jH1EhgOdV/h0y4GMp9pK+DF2TJNole8/vnsGUs5JDBNMdAGadl+hki3UsdWl9hwslairxqmH0fYLqXXiJgSmc0VI4KuVNFsEA2JCXCcpyyU56228Y1cBC2Jgm/IvcAlpnfDR9oMmIKZqes9lkAzUuLtNj9P9o2PM0ynzI88ILkk0k2Z371EFsLgg/B6bObg/Il8xviAORfpHrS2bAWJOVU7DYEM8qtP2UXcJ2H1EXjPydmjV5ZMWRTgjMSUDDSRNzqHrBAvWBw== 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=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=KXqM//NQ+ysAHEKZp2WurCborK3eF6VEZ1fJI6P1LIA=; b=IVeGLTMmrTyGnzwbiXXs5mIyYT7WJMIXFE3uJQJ2iRuN90+d+sfkl77C8sipPKyAKXUDlzfpztoBt2pMNzrsT1XpxlJPW28c5XXS1tdICNH4Fu4ScWzkP3q/yPSdTjcEWlC2G698lKCRneI8Mvk9lyMPvcfhSzqBqcV+i6dq0P4= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from AM6PR04MB4838.eurprd04.prod.outlook.com (2603:10a6:20b:4::16) by PAXPR04MB9256.eurprd04.prod.outlook.com (2603:10a6:102:2ba::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6745.34; Tue, 5 Sep 2023 21:39:07 +0000 Received: from AM6PR04MB4838.eurprd04.prod.outlook.com ([fe80::aa90:117d:c1d0:346a]) by AM6PR04MB4838.eurprd04.prod.outlook.com ([fe80::aa90:117d:c1d0:346a%3]) with mapi id 15.20.6745.030; Tue, 5 Sep 2023 21:39:07 +0000 From: Frank Li To: miquel.raynal@bootlin.com Cc: Frank.Li@nxp.com, alexandre.belloni@bootlin.com, conor.culhane@silvaco.com, imx@lists.linux.dev, linux-i3c@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 3/9] i3c: master: svc return actual transfer data len Date: Tue, 5 Sep 2023 17:38:36 -0400 Message-Id: <20230905213842.3035779-4-Frank.Li@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230905213842.3035779-1-Frank.Li@nxp.com> References: <20230905213842.3035779-1-Frank.Li@nxp.com> X-ClientProxiedBy: SJ0PR03CA0215.namprd03.prod.outlook.com (2603:10b6:a03:39f::10) To AM6PR04MB4838.eurprd04.prod.outlook.com (2603:10a6:20b:4::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AM6PR04MB4838:EE_|PAXPR04MB9256:EE_ X-MS-Office365-Filtering-Correlation-Id: 1fa53bd6-43ab-43fb-60c1-08dbae588880 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 2ias2/aIhxpzuTonShQajFzoQn2143LncfIpSJMaHkQ5hfSnfZ+w4bjcwJ+ixmss40lVL/hdegcL3cyy5iHSCTFt8t7mTnulu7WJxmAnT8tHxsDWvArJj3DRXe1mMNP68qFPhX3FGPwOAV+mSlpkkWwFuFDgJpdFgeX8HqywAZV/EX+YvOzPNJiCrj4HQgHr6eWMTd2GzAMVObEGfcMIaCydy/EIYflRO5P+W2xU99q0g7mKUZf/HCD8zcpWQdoVUH/UT2i7HV/sH8v9aeOeVabmgfFkXZSY2vgFv4Arf9t+Ihc6FjEeTu092p7qIR5cHP4vDaxMdHLTz0JI83SIs/R113AT4d3f2Wtwx1O/CXaFOmj2mcxzx4a6eTUbOAb2EhGdZ6COyCxvivzXwRD1fvsORXr7giMgWkGa68lcxuiZNTNB7/2X2sfo4xm56iqPzgBojmykMHyhLluaqWeK4dZQWl/3XGXU0Ay/D8/cnC3e/7zkAUC/hav54B8rA+PaNPcE5bISUTynoRNp2aC6Uwu4chIh9wC2/vUKAcnuZ24YiuF2jxqzX7vRhQZfIDlDVzEWZcm67v/6ulzIgIjuvWhl6o0KJxG2G+NuhUztEcKr02yJSNuQyCE3QlnYms7U X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:AM6PR04MB4838.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(396003)(376002)(39860400002)(366004)(346002)(136003)(186009)(1800799009)(451199024)(2906002)(83380400001)(6486002)(52116002)(6506007)(6916009)(316002)(66946007)(66556008)(66476007)(478600001)(26005)(6666004)(5660300002)(1076003)(41300700001)(8676002)(8936002)(6512007)(2616005)(4326008)(36756003)(38100700002)(38350700002)(86362001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: A1zc4jwhL+V9y6rpfU2jC1mq1GDKyobdHT5q58cc3UaBqHQlsJgO0i7f4y6soOBYmAGvlsFOCnEoL/6AXyAZfDslBY2Z/2ZwM7wLr+lbH2iu+YmW5Rcrhk3wWo25AVlbSAQp1aWm4Lx/u4uCg8aJQjQI95vfJ3I6vdZ8dKsEJCdzYeUzEAh9exNsWNwwaMviojXTM10LcFAufroGBEvyZVyEcIVLT2t/MLV9FS6yUEYBkYpQfpXNa2/blaYXWkij8NSj6doU0p4yi2Ryq1AlWjOebDIu/EgYLqV3Ilpt2xZ322ZjXYuLGCKaexEAHHmiB1lHti1u9jMfyqeVrZOY7i60tDCXlVl4+LKctMGd/+XyvUniSG0w5KntMsWE/5oxh63KA9qZEsUlQjdmGZNtYo/HyXI51BRelUiaSxmvEQGIuWf+t/BFrdDmcWJ5nKSZwf5zDRbaHlIYsCyKQRib0MPoaIzfzKcCOSdJy8AwsnONhKKI/FbtwH8uCrceF5HXXpnHbPg+xcjvKhiPluYLgc4U4PANo25JaIGR39iFdfxvAElUcDlyzp2bAKKdVI3iDxHADOjpVFChanCecNJ5OtiXsNxhKwtMkD7sDz7z5GChBsQeE2K0Z3TQlX/il4AiGR5G7D0MgrucBzckFBVA6h3ALnfJhSUBr2FeMBz7SLOZXfCEPX8CmiXLnOuiWjJ9M5wMLA5Ebl+oEbjAOWg6TX1daOxH3YLiNKpkUYRGxA89KaQwFWRMba5KwxmM2RY2WbAhS5e9rH7oahl+m4z0VJJYHKu5YNohsDYy6WnGfLNneZDHwzzrw31SCgEJK31IC7oKFtJHd2CW2o0uBNSh7Ex1mHLdo00+D0XvEc9JWIHeA826pgAZe4K7CLRDz/p5fVkYLEAIJN2yuKihe6UFGFy+Cr0peWDas1qpi0U7VYNCrXeeM8GfsqzMHIytJbWJLYkd7CjUrbiahI2DjJMkY59MFO1pjV7G4onvgs6RkylU3mDAfL0lCDE33TJDSEL68TwgSVopjbvgMzd7UPDF0nLiu4q43YZzy8k4BN1bxAMWQiaN7hYGO2Ej5XyS+miMYL21zdC/QUM05db2AwceLkhi23vF0kTQhPVAUGlBOvICqzUAVEqVuv8ozViAUEAV2GO/2BEO5VeGkdefiDNvl+o+eYwPpJjcOC8Zxf3ih6xn1vPgfPlUiUNwBBh29S1ew7aZxbG4/XEjO/VG8JeRX1Urb+Q4RqeMZGbSylQD/5b6bGgNFHgDPNADFZfUDrzw3oFb1sF0lH1m4yfW62D+YY/5rxTZY4Om3xdGCKxRBxTuUU1XaOSPcNq22J5G/AB9x85DQ6PXjFckvnWKIq6bQ+UJDzfQn4CDNv3/bqqakrOwUAJOEhwZg6Ri/JZwL4VpvT8GD7mt6uqRaqEtEVy6wGH41b+rzP3W+x23uxuyN7DuXg+db2wzzRB9m9fyJPlReMIYZxlGLemO/aOY9NE+EhA0zFZzRdTco9dkhPVL0yVo5gkD4sUT/K8hxsWJkW2b1CHm/tbFoZnmJ91zZbsJlqbnmY+jZNllmbCq6EM1aywjIBf4YBL62tiC8rNzRNqJ X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1fa53bd6-43ab-43fb-60c1-08dbae588880 X-MS-Exchange-CrossTenant-AuthSource: AM6PR04MB4838.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Sep 2023 21:39:07.5037 (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: 0PqIXrNlmQNqm+rDN+p9IPJdPeXLZF9jZhlVnU3tfdYvvdVq2VuVnbXVuVZmfurTUKVBzcptVKcQAXy9aUMswQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB9256 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230905_143915_902294_7B89D90D X-CRM114-Status: GOOD ( 14.15 ) 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 I3C allow devices early terminate data transfer. So set "actual" to indicate how much data get by i3c_priv_xfer. Signed-off-by: Frank Li --- drivers/i3c/master/svc-i3c-master.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c index 14185ee7dd19b..74c4ce8789daf 100644 --- a/drivers/i3c/master/svc-i3c-master.c +++ b/drivers/i3c/master/svc-i3c-master.c @@ -134,6 +134,7 @@ struct svc_i3c_cmd { const void *out; unsigned int len; unsigned int actual_len; + struct i3c_priv_xfer *xfer; bool continued; }; @@ -972,12 +973,14 @@ static int svc_i3c_master_read(struct svc_i3c_master *master, } static int svc_i3c_master_write(struct svc_i3c_master *master, - const u8 *out, unsigned int len) + const u8 *out, unsigned int len, unsigned int *actual) { - int offset = 0, ret; + int ret; u32 mdctrl; - while (offset < len) { + *actual = 0; + + while (*actual < len) { ret = readl_poll_timeout(master->regs + SVC_I3C_MDATACTRL, mdctrl, !(mdctrl & SVC_I3C_MDATACTRL_TXFULL), @@ -989,10 +992,10 @@ static int svc_i3c_master_write(struct svc_i3c_master *master, * The last byte to be sent over the bus must either have the * "end" bit set or be written in MWDATABE. */ - if (likely(offset < (len - 1))) - writel(out[offset++], master->regs + SVC_I3C_MWDATAB); + if (likely(*actual < (len - 1))) + writel(out[(*actual)++], master->regs + SVC_I3C_MWDATAB); else - writel(out[offset++], master->regs + SVC_I3C_MWDATABE); + writel(out[(*actual)++], master->regs + SVC_I3C_MWDATABE); } return 0; @@ -1027,7 +1030,8 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master, if (rnw) ret = svc_i3c_master_read(master, in, xfer_len); else - ret = svc_i3c_master_write(master, out, xfer_len); + ret = svc_i3c_master_write(master, out, xfer_len, actual_len); + if (ret < 0) goto emit_stop; @@ -1047,6 +1051,10 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master, /* Wait idle if stop is sent. */ readl_poll_timeout(master->regs + SVC_I3C_MSTATUS, reg, SVC_I3C_MSTATUS_STATE_IDLE(reg), 0, 1000); + + if (!rnw) + *actual_len -= SVC_I3C_MDATACTRL_RXCOUNT( + readl(master->regs + SVC_I3C_MDATACTRL)); } return 0; @@ -1116,6 +1124,9 @@ static void svc_i3c_master_start_xfer_locked(struct svc_i3c_master *master) cmd->addr, cmd->in, cmd->out, cmd->len, &cmd->actual_len, cmd->continued); + if (cmd->xfer) + cmd->xfer->actual = cmd->actual_len; + if (ret) break; } @@ -1299,6 +1310,7 @@ static int svc_i3c_master_priv_xfers(struct i3c_dev_desc *dev, for (i = 0; i < nxfers; i++) { struct svc_i3c_cmd *cmd = &xfer->cmds[i]; + cmd->xfer = xfers + i; cmd->addr = master->addrs[data->index]; cmd->rnw = xfers[i].rnw; cmd->in = xfers[i].rnw ? xfers[i].data.in : NULL; From patchwork Tue Sep 5 21:38:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Li X-Patchwork-Id: 13375086 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 9B60ACA1010 for ; Tue, 5 Sep 2023 21:39:20 +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:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=YPp/QH3VxYiNI1Ry8HbiKFKsLuttbWzjbX+bLnFkkOI=; b=zdCVVrnZWL/Ykk qKxrRUJalQUQfrK+IoNUpxtMh9PaCtqjWYCLjh1gMiUIp2AC1MNogScnEcMcka+sF6wk2lTLW6yHl llSTbaVZ4us1nFuVcZjADQCr+shEoeQXWP9jDRp7wqhb78D1WHUWOK/WtWn68gCWeJGNVzZjDGz7z vxbljBdWwidYk0JqxRHOUnV8M+ZlZMIBZESLH4o1+Ov0km1yKOPcNu9yIwR+QwzSs+GHlKXbSXGDw xFBUgMASgPwcq7flnaaBDMYhPmuDyoqYp7rkC7lfH3TfZDT2Ybkl8nLVYdliMED7911dvofWClj3C eOgjtC+tsVTKv+5fdlGg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qddlY-006lkf-0u; Tue, 05 Sep 2023 21:39:20 +0000 Received: from mail-db3eur04on061b.outbound.protection.outlook.com ([2a01:111:f400:fe0c::61b] helo=EUR04-DB3-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qddlV-006lfI-1d for linux-i3c@lists.infradead.org; Tue, 05 Sep 2023 21:39:18 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=oYJ+/txD3I9cS5sE7Q1mzMiiL/doeAwWhS68H3XklDZdFHjExw4VJfqWtvsBVgFUXJENWcX4Yr6iTDDDCqfApB8R4gdynLvX2+JmxuZGtn6yqPrQOFkLDcpDsPVoBpiXxAi/LmYnFUJErGR7nUoVzFrWu8FkgBf568ruIw+tkIfnol7RLL7ug9kDDqIBGWp1SXIVmphx1VdimLNCvEHoarj6xLn0opE2PGouhTijaSjuG6whLLNAmrV8M5Uht54oeKxhIGnuc4o3pcILxuxu/4e3Ye03wQoRM0pBOtRU/MnUVi86lTCFMU5YLYYdyMeuHihFmpY27SakgxE0P0esYQ== 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=+uN6I6Z4DJB0PJc+5Fsp2zn4gVQWodcXvlY9kHyPjw0=; b=ZNqEFmfs+7OUEePsPB7hmDMrjyy9IB/bEZQfBjKAGd6JxCwK3soR/z/LWkaGvik6M0Q5xlX3chkIGPm4lUkBEOWVfsuaxfKyggWYWLtPqi2nVAYCaY4KsHVxx4AS/aJOUDTPwRYUE+oFtzwCclWh02YItV8KrZWWMc1nVJsSHdKO5yiFT7HlgADC6Zq0Eq90cYasuCE6tywp/4fg80kzAlXOE5+sYpXPWryaBQcOR22V+OD/LLFz+F52HHlZYuzZyMq4hrQKNh4lv5UIyqz7y7PopZbtG2BDMAHnSRj1dN60p+3XDG7G4DCd2lCPgfL06BAClRvaFfe5Y5qPVJBEng== 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=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=+uN6I6Z4DJB0PJc+5Fsp2zn4gVQWodcXvlY9kHyPjw0=; b=eL6M2RvLIMC9MnnTj/d2RdYMQpfCrxWWdlP8xfaXXnxPnzT82ho/df3UG2e5EoMy2iR2IHntSqzdICelmX2ZzHdPcLvD1tWyxUyJM/AaaABVmVnPJ5p8XII5NWy6w5lWQL6JDUItThO/QK1/XYv3qmMwzg22P6qiQcMpOY656Ws= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from AM6PR04MB4838.eurprd04.prod.outlook.com (2603:10a6:20b:4::16) by PAXPR04MB9256.eurprd04.prod.outlook.com (2603:10a6:102:2ba::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6745.34; Tue, 5 Sep 2023 21:39:09 +0000 Received: from AM6PR04MB4838.eurprd04.prod.outlook.com ([fe80::aa90:117d:c1d0:346a]) by AM6PR04MB4838.eurprd04.prod.outlook.com ([fe80::aa90:117d:c1d0:346a%3]) with mapi id 15.20.6745.030; Tue, 5 Sep 2023 21:39:09 +0000 From: Frank Li To: miquel.raynal@bootlin.com Cc: Frank.Li@nxp.com, alexandre.belloni@bootlin.com, conor.culhane@silvaco.com, imx@lists.linux.dev, linux-i3c@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 4/9] dt-bindings: i3c: svc: add compatible string i3c: silvaco,i3c-slave-v1 Date: Tue, 5 Sep 2023 17:38:37 -0400 Message-Id: <20230905213842.3035779-5-Frank.Li@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230905213842.3035779-1-Frank.Li@nxp.com> References: <20230905213842.3035779-1-Frank.Li@nxp.com> X-ClientProxiedBy: SJ0PR03CA0215.namprd03.prod.outlook.com (2603:10b6:a03:39f::10) To AM6PR04MB4838.eurprd04.prod.outlook.com (2603:10a6:20b:4::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AM6PR04MB4838:EE_|PAXPR04MB9256:EE_ X-MS-Office365-Filtering-Correlation-Id: 693c9e3b-ba16-4a4d-c1b5-08dbae5889cb X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: f/+vaD92LLXYTPvUcgB1Hcz+KnVCc9nuaeEmUhIzWSbk6P64qg21W0pyKrMckEyGjuSvL6k1fu+Lvr88GBFJA6QJEQeEv/j8jod4oPPcFMHihWui1zJQjEALWiYg2LEd8FKWJsHBGrAzy6RgD7tCCn1uZdZTKr3WjfYAmuV0OsJ5TLoocdQPkG1VpP9NuFL5po29kezz7zDFXOid62bX0fF4GrnjsWxitIOEVCb9oj7b1xq/32Zvc+n3stB1hW/hABhefNTVpNASe1Gjjd+tmgvVk07hqLrOL87qMvDwn8IE7Lhx5TA+LFcb2gBvZW5pL2caGaqCS+RoyTNxeoeclPjxCiLBu0Et1EmBac9BiIJit4SX91Oyr6WvCmYj6uGzSWSQzPdLgfhNXZrZP24T/htdS1F/X6JWdjtwPFQIb+JstAg8WEYys/wu5Oy0cT3U4olP+zn5MhzKl6h6GH6+xwi+fsehJOmOPjTvOBnCdQViYHonHWP0rVkyTjE0kNLWWI47bNqxwHF6tPaqPk1DgIr7wzpNTeZHCJMpnwxPXpHf/SQ3zJVFePtVB/hpZXIBgLzMEEOhD7ysujpTCSnPXTaexoAwhVEpd39Vd7++C5N4RetFpCEtrNK0Kp/JOPXdJ/iWeb6pFwqjHbwv4sgyYg== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:AM6PR04MB4838.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(396003)(376002)(39860400002)(366004)(346002)(136003)(186009)(1800799009)(451199024)(2906002)(4744005)(83380400001)(6486002)(52116002)(6506007)(6916009)(316002)(66946007)(66556008)(66476007)(966005)(478600001)(26005)(6666004)(5660300002)(1076003)(41300700001)(8676002)(8936002)(6512007)(2616005)(4326008)(36756003)(38100700002)(38350700002)(86362001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: jbGS+NYvscYqqfn7uE5tIxaLQXsN9hN2IoyalaJ7D03K/rJ59d0gbizaC8QYEj7A7iUDdNf+2FG7gqUn6o3KXghsLGLnaelm/MnoGILAKJ7aobuLsvtmRwCKWrsi+DEgaFox1L7HU2N401nY8ulbnB5vAO2CLhYayDAi1/QcZE5TZ5IuGE2JksGmuc9rd61azjfcliwxE6YF8eQcRfILHUKDtb8MQLusCnUQaZgdH22G2hlNZj8jy3tkEC6Vn1jd7NvLACbfqnrqWaXnO77DQjilHXNCtAp4gLF0SVGlVnpigc1bi1MOegJaFQ5VMvZc/CsmbKuPaECS5zndDHVHHGltzxc32IwLLB+SO/cTgNOtTfhk86TdvLGCmvLSJ+BfxH1N6gw3G2XiQANIcCfceatGSiOZjHXM1LEthEGOcbAVWkfuEmwTmdkuZjnYjq2u1A8JoqshspHWpbXB0Ji/9swstqrXW445tiUlMUta2w9QYVy1lbROAYyKYkypg6ALuMnooNIwcTb2j2/Yw545pXJqeO2TqRM+5kUr317CTNVu7JpdSZcEt8sT6hrcy5zPiavEEx05dsKtjed4wcAS5K2iqHInjtXXnODzYJkJ2D3UWkkFEejo8SsPmWLuCPIsxDF0kIwhNLq7oc5OCiuk6Slahz97XEKLZa+tKRg2+/wT2mhGLTC4BHZ9WrvduAHQ2ODyDirW0iFyfoTE9LlKygs/6OfcCMTAGQAQwPDIe+bFNmUb7gKckAMWxQrPvQm70mxYt13JcZhOe0QO8xdgxOb+Gevek57W4JQ5pdaM2O4jNWXjdLRmH5WTw13nc8Ww+moMpxdbYJXBEd+E4ez4ttiKHEoJ/80YRTm0h1tnCrHXjBHRYoDrMY2cN7Dfl3e7CU/WzA7Qssbxe8Edlb9cOltdjLotlQXYeEXk4NlqL7OQKeSCSRbWsadKn0Rokj9p5gkrjzoYWty2+FhFYD90TDt1m4qSBakgOwUOy8KHdHtxspcK+YTXWqI15ilSbi72CjOfcGmaQ6BLpTPEjTOCD6cNCT6yTavK1ZCb+dSbtRIyFcIab0A/lrJ1G/aKTNllJtV/vmb+mGYsGzYKgcQzcaV+CsLyDTgSWciHw3PtdqoHsU4u+l/hkszNOB6El5pQlDv14UK0wteDSiiBnziam/sJMRh2BEMJ1OYrkFQApj6/dvoNIrob1MBfTh4ZLIZcQu3yuehlm6qVpSIRZOZVTmU0g0l1+Mtw+HmRXkXkg/z9MXEjQkB+m+AqBnmEjuDEg05HTZ6Zg2jTAnEWWeIRYakEvBdzVAvJVfGTgPHRoFl3LJT5uYW8XCnn2pwpkvC6g5hisCgJVrBOsLwoqXRSPiqD3dItDur1YibBWp5cAWiryJu4KhiCBXwi1pFdH1Gj2Yk81pB8WklxpfqG5OGzvVO+EPZXXuQYAfzvTF4Zm8zWZYNpU6ZKJoFqtxQ8qf1w8eIVMheFR11fj4kKqU0AKOWeItwVQIwai6WX0276SxBllal2YPN2IakD9ULZacM2FLODQSmhUWwC2pjwQ3yDZ7jAGo9sCHpkSV0eby6KMIwq1JcSoNhUJIqCmDusrcZF X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 693c9e3b-ba16-4a4d-c1b5-08dbae5889cb X-MS-Exchange-CrossTenant-AuthSource: AM6PR04MB4838.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Sep 2023 21:39:09.8125 (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: xqnfVud2duBKbaGU61mzzyk9Auoc3yrs4E3CLwBpJz7sciUZe2JFY30D2mrvc9g2YqkrIx574G9poo+9NdDxrg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB9256 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230905_143917_542334_D1BD3622 X-CRM114-Status: UNSURE ( 8.75 ) X-CRM114-Notice: Please train this message. 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 Add compatible string 'silvaco,i3c-slave-v1' for slave mode. Signed-off-by: Frank Li --- .../devicetree/bindings/i3c/silvaco,i3c-master.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/i3c/silvaco,i3c-master.yaml b/Documentation/devicetree/bindings/i3c/silvaco,i3c-master.yaml index 133855f11b4f5..da8a2f358505a 100644 --- a/Documentation/devicetree/bindings/i3c/silvaco,i3c-master.yaml +++ b/Documentation/devicetree/bindings/i3c/silvaco,i3c-master.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/i3c/silvaco,i3c-master.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Silvaco I3C master +title: Silvaco I3C master/slave maintainers: - Conor Culhane @@ -14,7 +14,10 @@ allOf: properties: compatible: - const: silvaco,i3c-master-v1 + const: + enum: + - silvaco,i3c-master-v1 + - silvaco,i3c-slave-v1 reg: maxItems: 1 From patchwork Tue Sep 5 21:38:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Li X-Patchwork-Id: 13375087 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 274B1CA100D for ; Tue, 5 Sep 2023 21:39:25 +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:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=WOwXCoq7jFqDUP+fLnTpy4/axdQkgN8u4H4W3RLfbOw=; b=HdhtNqjN1Vkr1P SVxmEa0HG/mLV12WCR1xixQcSanyDuJynC8M/j+nInpnEq5JD7UK5sSLhMm4qvNmJjvbFJXYvcP2E 4ooeP4oksAZoHKZ5VhmfsjxBvxgmB9KOerkPetCHp4F3fZbnAFFehPRp2GxoXHx2BBu/SIcY49WiO EzzbDBI1l9wXeL4kYsZV+X75JJx7VmDHhUlmWeiyNZWL9S5/Q2Q7dnCVi7KCRJCiaycBTNV45qGj9 E844IwpIq8PMFcgUJIbS3ievpt15FYtpL9hiy0vRciFQX1cVDOllyu2931GY2b4RW+ApDcdlVYXea fDTXbBrLqh8SHY3l+ASw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qddlc-006lmf-2O; Tue, 05 Sep 2023 21:39:24 +0000 Received: from mail-db3eur04on061b.outbound.protection.outlook.com ([2a01:111:f400:fe0c::61b] helo=EUR04-DB3-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qddlX-006lfI-0T for linux-i3c@lists.infradead.org; Tue, 05 Sep 2023 21:39:23 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=LHcy47BZFPaWrs7bEG+9pgGza7gFZ+tlWLB9aJHY7PMPKNmFUoiCfsEe5BB04dLLzGm/k02q3mQoZhoL1EhGrMDM0E3AHjHkkx3GD8qWmK/V5QVFk8a64xowoC2WKIowViS68z58lXhVSgpRCmtrSEGcP+HNfpSelHuP4YNhg+mnDmey9pfEnPYHGbrpPlgod1zyoINLRlfv0/7a5vGaZkMGtjSjFGguD3rdGmaFZ9yAfeN9gDJRq3uOze2YWXs9RP+WDVx+Vu1tAF2j/HB028WAYP/kZgZzT+NblX0/5V5Td8uesmlOvEhmgBEMoSrvt8CRlpoSP8RzGWtppNsejA== 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=mqEkm1WQVB6CGBqi+RdouzixPBwVwf1jm2gPimrZxUs=; b=PwgVjd4lFEX6vXyRKQjYzOXKKfAzCQTmYx5SVyq1U2veMwjR/0hGX6zKNK5mXWEqfLzrsx1ZHYowvo9hHxVcgx3jtfoSVirsY/GF2Ipd/jcS8RB12xRf3LDEBALU2lT4SP1SALVyedKyIXmk9UBrqPfBk/OBurRDbzXOayYytgrmbLgBdQccxocG4r2D/WVXJDHciwk26QTUkdLfn7WK/DFzm2XZlC1B5TBPaDJpf6/uAE3qcQXGMyMcrwf+rlLsmHX7qaqBMautsSp/Sie/BByCLhNUr6z15CCFCXEQbDZgjgTRsa5HfbPFpTMFEE8hTEMxZoWoN6UMY6C6XOivug== 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=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=mqEkm1WQVB6CGBqi+RdouzixPBwVwf1jm2gPimrZxUs=; b=ns/gtM5bbZ3NQDGyhSvXFl4BvCq8z8PdspnHbiHn15/b+adYDZqr+ghe3p1WfjnYHCx6rO5+2eU1M3Fh2w6u9iJLw+7pz4XHQG1mT13csADbf6HqyuLOwnnKy9+VCuFtaBhB/Iv8hv0k3jg4s12ZfSYPfx2RabWqPMy1UQnDN3w= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from AM6PR04MB4838.eurprd04.prod.outlook.com (2603:10a6:20b:4::16) by PAXPR04MB9256.eurprd04.prod.outlook.com (2603:10a6:102:2ba::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6745.34; Tue, 5 Sep 2023 21:39:12 +0000 Received: from AM6PR04MB4838.eurprd04.prod.outlook.com ([fe80::aa90:117d:c1d0:346a]) by AM6PR04MB4838.eurprd04.prod.outlook.com ([fe80::aa90:117d:c1d0:346a%3]) with mapi id 15.20.6745.030; Tue, 5 Sep 2023 21:39:12 +0000 From: Frank Li To: miquel.raynal@bootlin.com Cc: Frank.Li@nxp.com, alexandre.belloni@bootlin.com, conor.culhane@silvaco.com, imx@lists.linux.dev, linux-i3c@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 5/9] i3c: add slave mode support Date: Tue, 5 Sep 2023 17:38:38 -0400 Message-Id: <20230905213842.3035779-6-Frank.Li@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230905213842.3035779-1-Frank.Li@nxp.com> References: <20230905213842.3035779-1-Frank.Li@nxp.com> X-ClientProxiedBy: SJ0PR03CA0215.namprd03.prod.outlook.com (2603:10b6:a03:39f::10) To AM6PR04MB4838.eurprd04.prod.outlook.com (2603:10a6:20b:4::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AM6PR04MB4838:EE_|PAXPR04MB9256:EE_ X-MS-Office365-Filtering-Correlation-Id: 2b2ad74a-644b-4c2a-3529-08dbae588b2a X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: VcCF7bUEDsUqODZwo571KPoX7f4CMU2wRuB58NNn55juX3eOevtGeY9za+CTAMIWFC3hkOjhzWaodkGozKa4sKvHpZ3KHKQJ2LsOaeNOsGSkvV9SKfIhSirZaSW58w/6GHWbNn405aujWd1oYId1axF6iaUTNsQQwix8mjvD55AiDXurM9mTOOUPNbN9aSeZm9zA57IpqW8p3Q+9p7gv30x8i5JmecYx+3ehbKwknFLuA5LLI8kTSPXK+OUpE5elNIFS+eRSx9bdNW7NJHdPDoYKSv0dixbt41YeysKS8XNU6Z7PbCLC5APPHFi+lRi8kYRlYIV1v1g+E5NFQUf9T+UStp8nicDv4HdKGji2pqA9Uc58MdOpNLY0BHIaG90f2X3JBFRg7T/aknIyxPZNSCfwIeXF27WOiMBx0je7pWyLtNq88LbsII52XiYkB+OUZHWdu3qVbhNaTBz7igld6KE12TrcQiSk7GiIwrux4EY8nF8rMvecbzJcef/f3jivItAzevkQhc47pwNAVtkiktpfvRVLlTBikofU/kWlv7+qQqsq81nCFW7Ww0BbXTaEkS/QPsb5jA7NGKDxqcYGtvIChMU+47xrGqS9FYXVnq3QDRpkBTv+R4g8MDWBEQXe X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:AM6PR04MB4838.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(396003)(376002)(39860400002)(366004)(346002)(136003)(186009)(1800799009)(451199024)(2906002)(30864003)(83380400001)(6486002)(52116002)(6506007)(6916009)(316002)(66946007)(66556008)(66476007)(478600001)(26005)(6666004)(5660300002)(1076003)(41300700001)(8676002)(8936002)(6512007)(2616005)(4326008)(36756003)(38100700002)(38350700002)(86362001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: oHzm1gZOwMmCTeIeBnoi3ANsV0inSGIzxP1RH+uC5/rBruPQPnYzU3vNeshRVUczXMejcawzAzx4c7F8sWnEg/Cok0cjbaGjhCBDSa85Jyb0CDXpyCC+Qc3XQHpSeXRbAqay6wXzfDoF6D//XenRxD4KPZdfj5FyddJNzpW2C44lV1P4sFkIf2B0mhWgaV+WDPOjyeyizj6mmcpV/zRqMICjPpLA9h67d+gWjKgXTOnHZ3vCvIUNVxbjkkJtpYB8DqFYyfXPKEMJfEZIO99ppe909Au0jCbFQIMFYHUO+VwJL/dHRX5B5giMxImCMsg3yVpfrDwmlC6qylzjaOMpUKvWyXGKofCslqBWz88rZ1nNW+P1kUetE+HVefbbuN17OQ5+KyUz9etVeJ2dX0XSKtSJqgnTfUsS/AaU4xEJLtINhytbBwzTVVXVQyzqTLu7c2i3xofDS+Jq9lsbXcv7EYFUcLzmETlnVWkEn2G/yyxHlI6t4IheGpDEuuRhL2NI0dpK3guipf+eafG1/ec0hgCNEPzPenGonQMyGmnHZNnI79hBKq4j4CE16pSb0l6FVn0nXlCDchbIeja8fM76mydEPIM6EUsGxEK6XCZsbQLQ7bNohtWBqoF7bvds3Imm4ChlMT+O3iDQcsLEwEH7CJpnogoXEf9Z2FqYLNrzJDMmqInbNF9gmagtMQWCEaIBOc+L3fwXn8hUQ3ge+mwE2cShJ6BKeJ6yNCmkAKSe0zBxFswdlKAg1Nk+xz7QZMP5DHODgQt4Esf90q3+g9apMT8CFgJt4Um26LRkQ3StivMUCMA9ejAhX1VdmuY19T63MPX5Y4kjSb9HV03tMoU5PhVIEQGLCHQnWRx5PwmZmqRqhfjdySEKlIBX4SblHrHY72Xb905Vf5Eusbw2UjJ/TBWimSCW90jy5oESABKE0MKhGAkGR0HzlbUltQN3a/54rzLwlBPYEwmfUHDhO2aLL1DYybMXsuyBuVFipjks5yc4P4DiqW2JEg3OjryQjXJbOwdmT77cHm9XjSHIexCwQGA/zEzZNCw2kVFgBr3Z6VK1hYRaLAPDiMzcS4LtPmRmH6BQPCSreRI0+lu/LGyevRisl4E6QWpeXhmBUBgVxX2h2lQbpsoptWTowHab001Hh8RlXuuX/YzjZrL12eQbG3P1kaqXts+KpgRVzmZwrM2M7cdeDgMSsf7bbAW8s+sVKRq/6BploKJnuQ7TJ1EO+LmJzkX3fZW1tj+rb6wwp38QYV2crBHzFk08Vr8sB8M4sYckIRptfSULDrZC3pbfNr3Frlh9enX31TpZ6L2MVyiMfHPXXeU6Kh8VZ3TtW913xJnjTaBpxOtkGXxqfXM6ma3m1Qs6WipCdm0Imq31L8j6V6Ajy+0W9NZugrf1wJqqi0C8YpbkBylVr0oErYt1eNYmcD7zymN7E3QvVgH7f/aIKPmLRXybypG3dkHjZgXtEaOI8Wm3XqiQfu/j556q6wnhx+PQQyzOXt3W59sTOSDSurd7jRlGiklmTciPzw3yQSa2hkMuySgbfSK0BEKQw33ClfvX8zHkrRX1yPELFioOO/A2oLbk0rzEeZNngld5 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2b2ad74a-644b-4c2a-3529-08dbae588b2a X-MS-Exchange-CrossTenant-AuthSource: AM6PR04MB4838.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Sep 2023 21:39:12.1064 (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: U1S/IC+8GUp1eOiY0jnKnIrfLEA4+3GNVEhp5Wd4UOQfuREiFQ53AXzS+ZdbYPNL4hrIB6N4zoIY2qOrAqN2sw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB9256 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230905_143919_194988_B8AAD295 X-CRM114-Status: GOOD ( 23.12 ) 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 Introduce a new slave core layer in order to support slave functions in linux kernel. This comprises the controller library and function library. Controller library implements functions specific to an slave controller and function library implements functions specific to an slave function. Introduce a new configfs entry to configure the slave function configuring and bind the slave function with slave controller. Signed-off-by: Frank Li --- drivers/i3c/Kconfig | 29 +++ drivers/i3c/Makefile | 2 + drivers/i3c/i3c-cfs.c | 361 ++++++++++++++++++++++++++++++ drivers/i3c/slave.c | 441 ++++++++++++++++++++++++++++++++++++ include/linux/i3c/slave.h | 458 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 1291 insertions(+) create mode 100644 drivers/i3c/i3c-cfs.c create mode 100644 drivers/i3c/slave.c create mode 100644 include/linux/i3c/slave.h diff --git a/drivers/i3c/Kconfig b/drivers/i3c/Kconfig index 30a441506f61c..bdc173bc0da12 100644 --- a/drivers/i3c/Kconfig +++ b/drivers/i3c/Kconfig @@ -22,3 +22,32 @@ menuconfig I3C if I3C source "drivers/i3c/master/Kconfig" endif # I3C + +config I3C_SLAVE + bool "I3C Slave Support" + help + Support I3C Slave Mode. + + Enable this configuration option to support configurable I3C slave. + This should be enabled if the platform has a I3C controller that can + operate in slave mode. + + Enabling this option will build the I3C slave library, which includes + slave controller library and slave function library. + + If in doubt, say "N" to disable slave support. + +config I3C_SLAVE_CONFIGFS + bool "I3C Slave Configfs Support" + depends on I3C_SLAVE + select CONFIGFS_FS + help + Configfs entry for slave function and controller. + + This will enable the configfs entry that can be used to configure + the slave function and used to bind the function with a slave + controller. + +if I3C_SLAVE +source "drivers/i3c/slave/Kconfig" +endif #I#C_SLAVE diff --git a/drivers/i3c/Makefile b/drivers/i3c/Makefile index 11982efbc6d91..6407ddec3a4a9 100644 --- a/drivers/i3c/Makefile +++ b/drivers/i3c/Makefile @@ -2,3 +2,5 @@ i3c-y := device.o master.o obj-$(CONFIG_I3C) += i3c.o obj-$(CONFIG_I3C) += master/ +obj-$(CONFIG_I3C_SLAVE) += slave.o +obj-$(CONFIG_I3C_SLAVE_CONFIGFS) += i3c-cfs.o diff --git a/drivers/i3c/i3c-cfs.c b/drivers/i3c/i3c-cfs.c new file mode 100644 index 0000000000000..1f53fada43645 --- /dev/null +++ b/drivers/i3c/i3c-cfs.c @@ -0,0 +1,361 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Configfs to configure the I3C Slave + * + * Copyright (C) 2023 NXP + * Author: Frank Li + */ + +#include +#include +#include +#include +#include + +static DEFINE_MUTEX(functions_mutex); +static struct config_group *functions_group; +static struct config_group *controllers_group; + +struct i3c_slave_func_group { + struct config_group group; + struct i3c_slave_func *func; +}; + +struct i3c_slave_ctrl_group { + struct config_group group; + struct i3c_slave_ctrl *ctrl; +}; + +static inline struct i3c_slave_func_group *to_i3c_slave_func_group(struct config_item *item) +{ + return container_of(to_config_group(item), struct i3c_slave_func_group, group); +} + +static inline struct i3c_slave_ctrl_group *to_i3c_slave_ctrl_group(struct config_item *item) +{ + return container_of(to_config_group(item), struct i3c_slave_ctrl_group, group); +} + +static int i3c_slave_ctrl_func_link(struct config_item *ctrl_cfg, struct config_item *func_cfg) +{ + struct i3c_slave_func_group *func_group = to_i3c_slave_func_group(func_cfg); + struct i3c_slave_ctrl_group *ctrl_group = to_i3c_slave_ctrl_group(ctrl_cfg); + struct i3c_slave_ctrl *ctrl = ctrl_group->ctrl; + struct i3c_slave_func *func = func_group->func; + int ret; + + ret = i3c_slave_ctrl_add_func(ctrl, func); + if (ret) + return ret; + + ret = i3c_slave_func_bind(func); + if (ret) { + i3c_slave_ctrl_remove_func(ctrl, func); + return ret; + } + + return 0; +} + +static void i3c_slave_ctrl_func_unlink(struct config_item *ctrl_cfg, struct config_item *func_cfg) +{ + struct i3c_slave_func_group *func_group = to_i3c_slave_func_group(func_cfg->ci_parent); + struct i3c_slave_ctrl_group *ctrl_group = to_i3c_slave_ctrl_group(ctrl_cfg); + struct i3c_slave_ctrl *ctrl = ctrl_group->ctrl; + struct i3c_slave_func *func = func_group->func; + + i3c_slave_func_unbind(func); + i3c_slave_ctrl_remove_func(ctrl, func); +} + +static struct configfs_item_operations i3c_slave_ctrl_item_ops = { + .allow_link = i3c_slave_ctrl_func_link, + .drop_link = i3c_slave_ctrl_func_unlink, +}; + +static const struct config_item_type i3c_slave_ctrl_type = { + .ct_item_ops = &i3c_slave_ctrl_item_ops, + .ct_owner = THIS_MODULE, +}; + +/** + * i3c_slave_cfs_add_ctrl_group() - add I3C slave controller group + * @ctrl: I3C slave controller device + * + * Return: Pointer to struct config_group + */ +struct config_group *i3c_slave_cfs_add_ctrl_group(struct i3c_slave_ctrl *ctrl) +{ + struct i3c_slave_ctrl_group *ctrl_group; + struct config_group *group; + int ret; + + ctrl_group = kzalloc(sizeof(*ctrl_group), GFP_KERNEL); + if (!ctrl_group) { + ret = -ENOMEM; + goto err; + } + + group = &ctrl_group->group; + + config_group_init_type_name(group, dev_name(&ctrl->dev), &i3c_slave_ctrl_type); + ret = configfs_register_group(controllers_group, group); + if (ret) { + pr_err("failed to register configfs group for %s\n", dev_name(&ctrl->dev)); + goto err_register_group; + } + + ctrl_group->ctrl = ctrl; + + return group; + +err_register_group: + kfree(ctrl_group); + +err: + return ERR_PTR(ret); +} +EXPORT_SYMBOL(i3c_slave_cfs_add_ctrl_group); + +/** + * i3c_slave_cfs_remove_ctrl_group() - remove I3C slave controller group + * @group: the group to be removed + */ +void i3c_slave_cfs_remove_ctrl_group(struct config_group *group) +{ + struct i3c_slave_ctrl_group *ctrl_group; + + if (!group) + return; + + ctrl_group = container_of(group, struct i3c_slave_ctrl_group, group); + i3c_slave_ctrl_put(ctrl_group->ctrl); + configfs_unregister_group(&ctrl_group->group); + kfree(ctrl_group); +} +EXPORT_SYMBOL(i3c_slave_cfs_remove_ctrl_group); + +#define I3C_SLAVE_ATTR_R(_name) \ +static ssize_t i3c_slave_func_##_name##_show(struct config_item *item, char *page) \ +{ \ + struct i3c_slave_func *func = to_i3c_slave_func_group(item)->func; \ + return sysfs_emit(page, "0x%04x\n", func->_name); \ +} + +#define I3C_SLAVE_ATTR_W(_name, _u) \ +static ssize_t i3c_slave_func_##_name##_store(struct config_item *item, \ + const char *page, size_t len) \ +{ \ + _u val; \ + struct i3c_slave_func *func = to_i3c_slave_func_group(item)->func; \ + if (kstrto##_u(page, 0, &val) < 0) \ + return -EINVAL; \ + func->_name = val; \ + return len; \ +} + +I3C_SLAVE_ATTR_R(vendor_id); +I3C_SLAVE_ATTR_W(vendor_id, u16); +CONFIGFS_ATTR(i3c_slave_func_, vendor_id); + +I3C_SLAVE_ATTR_R(vendor_info); +I3C_SLAVE_ATTR_W(vendor_info, u16); +CONFIGFS_ATTR(i3c_slave_func_, vendor_info); + +I3C_SLAVE_ATTR_R(part_id); +I3C_SLAVE_ATTR_W(part_id, u16); +CONFIGFS_ATTR(i3c_slave_func_, part_id); + +I3C_SLAVE_ATTR_R(instance_id); +I3C_SLAVE_ATTR_W(instance_id, u8); +CONFIGFS_ATTR(i3c_slave_func_, instance_id); + +I3C_SLAVE_ATTR_R(ext_id); +I3C_SLAVE_ATTR_W(ext_id, u16); +CONFIGFS_ATTR(i3c_slave_func_, ext_id); + +I3C_SLAVE_ATTR_R(max_write_len); +I3C_SLAVE_ATTR_W(max_write_len, u16); +CONFIGFS_ATTR(i3c_slave_func_, max_write_len); + +I3C_SLAVE_ATTR_R(max_read_len); +I3C_SLAVE_ATTR_W(max_read_len, u16); +CONFIGFS_ATTR(i3c_slave_func_, max_read_len); + +I3C_SLAVE_ATTR_R(bcr); +I3C_SLAVE_ATTR_W(bcr, u8); +CONFIGFS_ATTR(i3c_slave_func_, bcr); + +I3C_SLAVE_ATTR_R(dcr); +I3C_SLAVE_ATTR_W(dcr, u8); +CONFIGFS_ATTR(i3c_slave_func_, dcr); + +static struct configfs_attribute *i3c_slave_func_attrs[] = { + &i3c_slave_func_attr_vendor_id, + &i3c_slave_func_attr_vendor_info, + &i3c_slave_func_attr_part_id, + &i3c_slave_func_attr_instance_id, + &i3c_slave_func_attr_ext_id, + &i3c_slave_func_attr_max_write_len, + &i3c_slave_func_attr_max_read_len, + &i3c_slave_func_attr_bcr, + &i3c_slave_func_attr_dcr, + NULL, +}; + +static const struct config_item_type i3c_slave_func_type = { + .ct_attrs = i3c_slave_func_attrs, + .ct_owner = THIS_MODULE, +}; + +static struct config_group *i3c_slave_func_make(struct config_group *group, const char *name) +{ + struct i3c_slave_func_group *func_group; + struct i3c_slave_func *func; + int err; + + func_group = kzalloc(sizeof(*func_group), GFP_KERNEL); + if (!func_group) + return ERR_PTR(-ENOMEM); + + config_group_init_type_name(&func_group->group, name, &i3c_slave_func_type); + + func = i3c_slave_func_create(group->cg_item.ci_name, name); + if (IS_ERR(func)) { + pr_err("failed to create i3c slave function device\n"); + err = -EINVAL; + goto free_group; + } + + func->group = &func_group->group; + + func_group->func = func; + + return &func_group->group; + +free_group: + kfree(func_group); + + return ERR_PTR(err); +} + +static void i3c_slave_func_drop(struct config_group *group, struct config_item *item) +{ + config_item_put(item); +} + +static struct configfs_group_operations i3c_slave_func_group_ops = { + .make_group = &i3c_slave_func_make, + .drop_item = &i3c_slave_func_drop, +}; + +static const struct config_item_type i3c_slave_func_group_type = { + .ct_group_ops = &i3c_slave_func_group_ops, + .ct_owner = THIS_MODULE, +}; + +/** + * i3c_slave_cfs_add_func_group() - add I3C slave function group + * @name: group name + * + * Return: Pointer to struct config_group + */ +struct config_group *i3c_slave_cfs_add_func_group(const char *name) +{ + struct config_group *group; + + group = configfs_register_default_group(functions_group, name, + &i3c_slave_func_group_type); + if (IS_ERR(group)) + pr_err("failed to register configfs group for %s function\n", + name); + + return group; +} +EXPORT_SYMBOL(i3c_slave_cfs_add_func_group); + +/** + * i3c_slave_cfs_remove_func_group() - add I3C slave function group + * @group: group to be removed + */ +void i3c_slave_cfs_remove_func_group(struct config_group *group) +{ + if (IS_ERR_OR_NULL(group)) + return; + + configfs_unregister_default_group(group); +} +EXPORT_SYMBOL(i3c_slave_cfs_remove_func_group); + +static const struct config_item_type i3c_slave_controllers_type = { + .ct_owner = THIS_MODULE, +}; + +static const struct config_item_type i3c_slave_functions_type = { + .ct_owner = THIS_MODULE, +}; + +static const struct config_item_type i3c_slave_type = { + .ct_owner = THIS_MODULE, +}; + +static struct configfs_subsystem i3c_slave_cfs_subsys = { + .su_group = { + .cg_item = { + .ci_namebuf = "i3c_slave", + .ci_type = &i3c_slave_type, + }, + }, + .su_mutex = __MUTEX_INITIALIZER(i3c_slave_cfs_subsys.su_mutex), +}; + +static int __init i3c_slave_cfs_init(void) +{ + int ret; + struct config_group *root = &i3c_slave_cfs_subsys.su_group; + + config_group_init(root); + + ret = configfs_register_subsystem(&i3c_slave_cfs_subsys); + if (ret) { + pr_err("Error %d while registering subsystem %s\n", + ret, root->cg_item.ci_namebuf); + goto err; + } + + functions_group = configfs_register_default_group(root, "functions", + &i3c_slave_functions_type); + if (IS_ERR(functions_group)) { + ret = PTR_ERR(functions_group); + pr_err("Error %d while registering functions group\n", + ret); + goto err_functions_group; + } + + controllers_group = + configfs_register_default_group(root, "controllers", + &i3c_slave_controllers_type); + if (IS_ERR(controllers_group)) { + ret = PTR_ERR(controllers_group); + pr_err("Error %d while registering controllers group\n", + ret); + goto err_controllers_group; + } + + return 0; + +err_controllers_group: + configfs_unregister_default_group(functions_group); + +err_functions_group: + configfs_unregister_subsystem(&i3c_slave_cfs_subsys); + +err: + return ret; +} +module_init(i3c_slave_cfs_init); + +MODULE_DESCRIPTION("I3C FUNC CONFIGFS"); +MODULE_AUTHOR("Frank Li "); + + diff --git a/drivers/i3c/slave.c b/drivers/i3c/slave.c new file mode 100644 index 0000000000000..edd7a2888271b --- /dev/null +++ b/drivers/i3c/slave.c @@ -0,0 +1,441 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * configfs to configure the I3C Slave + * + * Copyright (C) 2023 NXP + * Author: Frank Li + */ + +#include +#include +#include +#include +#include + +static DEFINE_MUTEX(func_lock); +static struct class *i3c_slave_ctrl_class; + +static void i3c_slave_func_dev_release(struct device *dev) +{ + struct i3c_slave_func *func = to_i3c_slave_func(dev); + + kfree(func->name); + kfree(func); +} + +static const struct device_type i3c_slave_func_type = { + .release = i3c_slave_func_dev_release, +}; + +static int i3c_slave_func_match_driver(struct device *dev, struct device_driver *drv) +{ + return !strncmp(dev_name(dev), drv->name, strlen(drv->name)); +} + +static int i3c_slave_func_device_probe(struct device *dev) +{ + struct i3c_slave_func *func = to_i3c_slave_func(dev); + struct i3c_slave_func_driver *driver = to_i3c_slave_func_driver(dev->driver); + + if (!driver->probe) + return -ENODEV; + + func->driver = driver; + + return driver->probe(func); +} + +static void i3c_slave_func_device_remove(struct device *dev) +{ + struct i3c_slave_func *func = to_i3c_slave_func(dev); + struct i3c_slave_func_driver *driver = to_i3c_slave_func_driver(dev->driver); + + if (driver->remove) + driver->remove(func); + func->driver = NULL; +} + +static const struct bus_type i3c_slave_func_bus_type = { + .name = "i3c_slave_func", + .probe = i3c_slave_func_device_probe, + .remove = i3c_slave_func_device_remove, + .match = i3c_slave_func_match_driver, +}; + +static void i3c_slave_ctrl_release(struct device *dev) +{ + kfree(to_i3c_slave_ctrl(dev)); +} + +static void devm_i3c_slave_ctrl_release(struct device *dev, void *res) +{ + struct i3c_slave_ctrl *ctrl = *(struct i3c_slave_ctrl **)res; + + i3c_slave_ctrl_destroy(ctrl); +} + +struct i3c_slave_ctrl * +__devm_i3c_slave_ctrl_create(struct device *dev, const struct i3c_slave_ctrl_ops *ops, + struct module *owner) +{ + struct i3c_slave_ctrl **ptr, *ctrl; + + ptr = devres_alloc(devm_i3c_slave_ctrl_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + ctrl = __i3c_slave_ctrl_create(dev, ops, owner); + if (!IS_ERR(ctrl)) { + *ptr = ctrl; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return ctrl; +} + +static int devm_i3c_slave_ctrl_match(struct device *dev, void *res, void *match_data) +{ + struct i3c_slave_ctrl **ptr = res; + + return *ptr == match_data; +} + +/** + * __i3c_slave_ctrl_create() - create a new slave controller device + * @dev: device that is creating the new slave controller + * @ops: function pointers for performing slave controller operations + * @owner: the owner of the module that creates the slave controller device + * + * Return: Pointer to struct i3c_slave_ctrl + */ +struct i3c_slave_ctrl * +__i3c_slave_ctrl_create(struct device *dev, const struct i3c_slave_ctrl_ops *ops, + struct module *owner) +{ + struct i3c_slave_ctrl *ctrl; + int ret; + + if (WARN_ON(!dev)) + return ERR_PTR(-EINVAL); + + ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); + if (!ctrl) + return ERR_PTR(-ENOMEM); + + device_initialize(&ctrl->dev); + ctrl->dev.class = i3c_slave_ctrl_class; + ctrl->dev.parent = dev; + ctrl->dev.release = i3c_slave_ctrl_release; + ctrl->ops = ops; + + ret = dev_set_name(&ctrl->dev, "%s", dev_name(dev)); + if (ret) + goto put_dev; + + ret = device_add(&ctrl->dev); + if (ret) + goto put_dev; + + ctrl->group = i3c_slave_cfs_add_ctrl_group(ctrl); + if (!ctrl->group) + goto put_dev; + + return ctrl; + +put_dev: + put_device(&ctrl->dev); + kfree(ctrl); + + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(__i3c_slave_ctrl_create); + +/** + * devm_i3c_slave_ctrl_destroy() - destroy the slave controller device + * @dev: device that is creating the new slave controller device + * @ops: function pointers for performing slave controller operations + * @owner: the owner of the module that creates the slave controller device + * + * Invoke to create a new slave controller device and add it to i3c_slave class. While at that, it + * also associates the device with the i3c_slave using devres. On driver detach, release function is + * invoked on the devres data, then devres data is freed. + */ +void devm_i3c_slave_ctrl_destroy(struct device *dev, struct i3c_slave_ctrl *ctrl) +{ + int r; + + r = devres_destroy(dev, devm_i3c_slave_ctrl_release, devm_i3c_slave_ctrl_match, + ctrl); + dev_WARN_ONCE(dev, r, "couldn't find I3C controller resource\n"); +} +EXPORT_SYMBOL_GPL(devm_i3c_slave_ctrl_destroy); + + + +/** + * i3c_slave_ctrl_destroy() - destroy the slave controller device + * @ctrl: the slave controller device that has to be destroyed + * + * Invoke to destroy the I3C slave device + */ +void i3c_slave_ctrl_destroy(struct i3c_slave_ctrl *ctrl) +{ + i3c_slave_cfs_remove_ctrl_group(ctrl->group); + device_unregister(&ctrl->dev); +} +EXPORT_SYMBOL_GPL(i3c_slave_ctrl_destroy); + +/** + * i3c_slave_ctrl_add_func() - bind I3C slave function to an slave controller + * @ctrl: the controller device to which the slave function should be added + * @func: the slave function to be added + * + * An I3C slave device can have only one functions. + */ +int i3c_slave_ctrl_add_func(struct i3c_slave_ctrl *ctrl, struct i3c_slave_func *func) +{ + if (ctrl->func) + return -EBUSY; + + ctrl->func = func; + func->ctrl = ctrl; + + return 0; +} +EXPORT_SYMBOL_GPL(i3c_slave_ctrl_add_func); + +/** + * i3c_slave_ctrl_remove_func() - unbind I3C slave function to an slave controller + * @ctrl: the controller device to which the slave function should be removed + * @func: the slave function to be removed + * + * An I3C slave device can have only one functions. + */ +void i3c_slave_ctrl_remove_func(struct i3c_slave_ctrl *ctrl, struct i3c_slave_func *func) +{ + ctrl->func = NULL; +} +EXPORT_SYMBOL_GPL(i3c_slave_ctrl_remove_func); + + +/** + * i3c_slave_ctrl() - get the I3C slave controller + * @name: device name of the slave controller + * + * Invoke to get struct i3c_slave_ctrl * corresponding to the device name of the + * slave controller + */ +struct i3c_slave_ctrl *i3c_slave_ctrl_get(const char *name) +{ + int ret = -EINVAL; + struct i3c_slave_ctrl *ctrl; + struct device *dev; + struct class_dev_iter iter; + + class_dev_iter_init(&iter, i3c_slave_ctrl_class, NULL, NULL); + while ((dev = class_dev_iter_next(&iter))) { + if (strcmp(name, dev_name(dev))) + continue; + + ctrl = to_i3c_slave_ctrl(dev); + if (!try_module_get(ctrl->ops->owner)) { + ret = -EINVAL; + goto err; + } + + class_dev_iter_exit(&iter); + get_device(&ctrl->dev); + return ctrl; + } + +err: + class_dev_iter_exit(&iter); + return ERR_PTR(ret); + +} +EXPORT_SYMBOL_GPL(i3c_slave_ctrl_get); + +/** + * i3c_slave_ctrl_put() - release the I3C endpoint controller + * @slave: slave returned by pci_slave_get() + * + * release the refcount the caller obtained by invoking i3c_slave_ctrl_get() + */ +void i3c_slave_ctrl_put(struct i3c_slave_ctrl *ctrl) +{ + if (!ctrl || IS_ERR(ctrl)) + return; + + module_put(ctrl->ops->owner); + put_device(&ctrl->dev); +} +EXPORT_SYMBOL_GPL(i3c_slave_ctrl_put); + +/** + * i3c_slave_func_bind() - Notify the function driver that the function device has been bound to a + * controller device + * @func: the function device which has been bound to the controller device + * + * Invoke to notify the function driver that it has been bound to a controller device + */ +int i3c_slave_func_bind(struct i3c_slave_func *func) +{ + struct device *dev = &func->dev; + int ret; + + if (!func->driver) { + dev_WARN(dev, "func device not bound to driver\n"); + return -EINVAL; + } + + if (!try_module_get(func->driver->owner)) + return -EAGAIN; + + mutex_lock(&func->lock); + ret = func->driver->ops->bind(func); + if (!ret) + func->is_bound = true; + mutex_unlock(&func->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(i3c_slave_func_bind); + +/** + * i3c_slave_func_unbind() - Notify the function driver that the binding between the function device + * and controller device has been lost + * @func: the function device which has lost the binding with the controller device + * + * Invoke to notify the function driver that the binding between the function device and controller + * device has been lost. + */ +void i3c_slave_func_unbind(struct i3c_slave_func *func) +{ + if (!func->driver) { + dev_WARN(&func->dev, "func device not bound to driver\n"); + return; + } + + mutex_lock(&func->lock); + if (func->is_bound) + func->driver->ops->unbind(func); + mutex_unlock(&func->lock); + + module_put(func->driver->owner); +} +EXPORT_SYMBOL_GPL(i3c_slave_func_unbind); + +/** + * i3c_slave_func_create() - create a new I3C function device + * @drv_name: the driver name of the I3C function device. + * @name: the name of the function device. + * + * Invoke to create a new I3C function device by providing the name of the function device. + */ +struct i3c_slave_func *i3c_slave_func_create(const char *drv_name, const char *name) +{ + struct i3c_slave_func *func; + struct device *dev; + int ret; + + func = kzalloc(sizeof(*func), GFP_KERNEL); + if (!func) + return ERR_PTR(-ENOMEM); + + dev = &func->dev; + device_initialize(dev); + dev->bus = &i3c_slave_func_bus_type; + dev->type = &i3c_slave_func_type; + mutex_init(&func->lock); + + ret = dev_set_name(dev, "%s.%s", drv_name, name); + if (ret) { + put_device(dev); + return ERR_PTR(ret); + } + + ret = device_add(dev); + if (ret) { + put_device(dev); + return ERR_PTR(ret); + } + + return func; +} +EXPORT_SYMBOL_GPL(i3c_slave_func_create); + +/** + * __i3c_slave_func_register_driver() - register a new I3C function driver + * @driver: structure representing I3C function driver + * @owner: the owner of the module that registers the I3C function driver + * + * Invoke to register a new I3C function driver. + */ +int __i3c_slave_func_register_driver(struct i3c_slave_func_driver *driver, struct module *owner) +{ + int ret = -EEXIST; + + if (!driver->ops) + return -EINVAL; + + if (!driver->ops->bind || !driver->ops->unbind) + return -EINVAL; + + driver->driver.bus = &i3c_slave_func_bus_type; + driver->driver.owner = owner; + + ret = driver_register(&driver->driver); + if (ret) + return ret; + + i3c_slave_cfs_add_func_group(driver->driver.name); + + return 0; +} +EXPORT_SYMBOL_GPL(__i3c_slave_func_register_driver); + +/** + * i3c_slave_func_unregister_driver() - unregister the I3C function driver + * @driver: the I3C function driver that has to be unregistered + * + * Invoke to unregister the I3C function driver. + */ +void i3c_slave_func_unregister_driver(struct i3c_slave_func_driver *fd) +{ + mutex_lock(&func_lock); + mutex_unlock(&func_lock); +} +EXPORT_SYMBOL_GPL(i3c_slave_func_unregister_driver); + +static int __init i3c_slave_init(void) +{ + int ret; + + i3c_slave_ctrl_class = class_create("i3c_slave"); + if (IS_ERR(i3c_slave_ctrl_class)) { + pr_err("failed to create i3c slave class --> %ld\n", + PTR_ERR(i3c_slave_ctrl_class)); + return PTR_ERR(i3c_slave_ctrl_class); + } + + ret = bus_register(&i3c_slave_func_bus_type); + if (ret) { + class_destroy(i3c_slave_ctrl_class); + pr_err("failed to register i3c slave func bus --> %d\n", ret); + return ret; + } + + return 0; +} +module_init(i3c_slave_init); + +static void __exit i3c_slave_exit(void) +{ + class_destroy(i3c_slave_ctrl_class); + bus_unregister(&i3c_slave_func_bus_type); + +} +module_exit(i3c_slave_exit); + diff --git a/include/linux/i3c/slave.h b/include/linux/i3c/slave.h new file mode 100644 index 0000000000000..a4cbbfc6d6ea9 --- /dev/null +++ b/include/linux/i3c/slave.h @@ -0,0 +1,458 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2023 NXP. + * + * Author: Frank Li + */ + +#ifndef I3C_SLAVE_H +#define I3C_SLAVE_H + +#include + +struct i3c_slave_func; +struct i3c_slave_ctrl; + +/** + * struct i3c_slave_func_ops - set of function pointers for performing i3c slave function operations + * @bind: ops to perform when a controller device has been bound to function device + * @unbind: ops to perform when a binding has been lost between a controller device and function + * device + */ +struct i3c_slave_func_ops { + int (*bind)(struct i3c_slave_func *func); + void (*unbind)(struct i3c_slave_func *func); +}; + +/** + * struct i3c_slave_func_driver - represents the I3C function driver + * @probe: ops to perform when a new function device has been bound to the function driver + * @remove: ops to perform when the binding between the function device and function driver is + * broken + * @driver: I3C Function driver + * @ops: set of function pointers for performing function operations + * @owner: the owner of the module that registers the I3C function driver + * @epf_group: list of configfs group corresponding to the I3C function driver + */ +struct i3c_slave_func_driver { + int (*probe)(struct i3c_slave_func *func); + void (*remove)(struct i3c_slave_func *func); + + char *name; + struct device_driver driver; + struct i3c_slave_func_ops *ops; + struct module *owner; +}; + +/** + * struct i3c_slave_func - represents the I3C function device + * @dev: the I3C function device + * @name: the name of the I3C function device + * @driver: the function driver to which this function device is bound + * @group: configfs group associated with the EPF device + * @lock: mutex to protect i3c_slave_func_ops + * @ctrl: binded I3C controller device + * @is_bound: indicates if bind notification to function driver has been invoked + * @vednor_id: vendor id + * @part_id: part id + * @instance_id: instance id + * @ext_id: ext id + * @vendor_info: vendor info + * @static_addr: static address for I2C. It is 0 for I3C. + * @max_write_len: maxium write length + * @max_read_len: maxium read length + * @bcr: bus characteristics register (BCR) + * @dcr: device characteristics register (DCR) + */ +struct i3c_slave_func { + struct device dev; + char *name; + struct i3c_slave_func_driver *driver; + struct config_group *group; + /* mutex to protect against concurrent access of i3c_slave_func_ops */ + struct mutex lock; + struct i3c_slave_ctrl *ctrl; + bool is_bound; + + u16 vendor_id; + u16 part_id; + u8 instance_id; + u16 ext_id; + u8 vendor_info; + u16 static_addr; + u16 max_write_len; //0 is hardware default max value + u16 max_read_len; //0 is hardware default max value + u8 bcr; + u8 dcr; +}; + +enum i3c_request_stat { + I3C_REQUEST_OKAY, + I3C_REQUEST_PARTIAL, + I3C_REQUEST_ERR, + I3C_REQUEST_CANCEL, +}; + +/** + * struct i3c_request - represents the an I3C transfer request + * @buf: data buffer + * @length: data length + * @complete: call back function when request finished or cancelled + * @context: general data for complete callback function + * @status: transfer status + * @actual: how much actually transferred + * @ctrl: I3C slave controller associate with this request + * @tx: transfer direction, 1: slave to master, 0: master to slave + */ +struct i3c_request { + void *buf; + unsigned int length; + + void (*complete)(struct i3c_request *req); + void *context; + struct list_head list; + + enum i3c_request_stat status; + unsigned int actual; + struct i3c_slave_ctrl *ctrl; + bool tx; +}; + +/** + * struct i3c_slave_ctrl_features - represents I3C slave controller features. + * @tx_fifo_sz: tx hardware fifo size + * @rx_fifo_sz: rx hardware fifo size + */ +struct i3c_slave_ctrl_features { + u32 tx_fifo_sz; + u32 rx_fifo_sz; +}; + +/** + * struct i3c_slave_ctrl_ops - set of function pointers for performing controller operations + * @set_config: set I3C controller configuration + * @enable: enable I3C controller + * @disable: disable I3C controller + * @raise_ibi: rasie IBI interrupt to master + * @queue: queue an I3C transfer + * @dequeue: dequeue an I3C transfer + * @cancel_all_reqs: call all pending requests + * @fifo_status: current FIFO status + * @fifo_flush: flush hardware FIFO + * @get_features: ops to get the features supported by the I3C slave controller + * @owner: the module owner containing the ops + */ +struct i3c_slave_ctrl_ops { + int (*set_config)(struct i3c_slave_ctrl *ctrl, struct i3c_slave_func *func); + int (*enable)(struct i3c_slave_ctrl *ctrl); + int (*disable)(struct i3c_slave_ctrl *ctrl); + int (*raise_ibi)(struct i3c_slave_ctrl *ctrl, void *p, u8 size); + + struct i3c_request *(*alloc_request)(struct i3c_slave_ctrl *ctrl, gfp_t gfp_flags); + void (*free_request)(struct i3c_request *req); + + int (*queue)(struct i3c_request *req, gfp_t gfp_flags); + int (*dequeue)(struct i3c_request *req); + + void (*cancel_all_reqs)(struct i3c_slave_ctrl *ctrl, bool tx); + + int (*fifo_status)(struct i3c_slave_ctrl *ctrl, bool tx); + void (*fifo_flush)(struct i3c_slave_ctrl *ctrl, bool tx); + + const struct i3c_slave_ctrl_features *(*get_features)(struct i3c_slave_ctrl *ctrl); + struct module *owner; +}; + +/** + * struct i3c_slave_ctrl - represents the I3C slave device + * @dev: I3C slave device + * @ops: function pointers for performing endpoint operations + * @func: slave functions present in this controller device + * @group: configfs group representing the I3C controller device + */ +struct i3c_slave_ctrl { + struct device dev; + const struct i3c_slave_ctrl_ops *ops; + struct i3c_slave_func *func; + struct config_group *group; +}; + +/** + * i3c_slave_ctrl_raise_ibi() - Raise IBI to master + * @ctrl: I3C slave controller + * @p: optional data for IBI + * @size: size of optional data + * + * Returns: Zero for success, or an error code in case of failure + */ +static inline int i3c_slave_ctrl_raise_ibi(struct i3c_slave_ctrl *ctrl, void *p, u8 size) +{ + if (ctrl && ctrl->ops && ctrl->ops->raise_ibi) + return ctrl->ops->raise_ibi(ctrl, p, size); + + return -EINVAL; +} + +/** + * i3c_slave_ctrl_cancel_all_reqs() - Cancel all pending request + * @ctrl: I3C slave controller + * @tx: Transfer diretion queue + * @size: size of optional data + */ +static inline void i3c_slave_ctrl_cancel_all_reqs(struct i3c_slave_ctrl *ctrl, bool tx) +{ + if (ctrl && ctrl->ops && ctrl->ops->cancel_all_reqs) + ctrl->ops->cancel_all_reqs(ctrl, tx); +} + +/** + * i3c_slave_ctrl_set_config() - Set controller configuration + * @ctrl: I3C slave controller device + * @func: Function device + * + * Returns: Zero for success, or an error code in case of failure + */ +static inline int +i3c_slave_ctrl_set_config(struct i3c_slave_ctrl *ctrl, struct i3c_slave_func *func) +{ + if (ctrl && ctrl->ops && ctrl->ops->set_config) + return ctrl->ops->set_config(ctrl, func); + + return -EINVAL; +} + +/** + * i3c_slave_ctrl_enable() - Enable I3C controller + * @ctrl: I3C slave controller device + * + * Returns: Zero for success, or an error code in case of failure + */ +static inline int +i3c_slave_ctrl_enable(struct i3c_slave_ctrl *ctrl) +{ + if (ctrl && ctrl->ops && ctrl->ops->enable) + return ctrl->ops->enable(ctrl); + + return -EINVAL; +} + +/** + * i3c_slave_ctrl_disable() - Disable I3C controller + * @ctrl: I3C slave controller device + * + * Returns: Zero for success, or an error code in case of failure + */ +static inline int +i3c_slave_ctrl_disable(struct i3c_slave_ctrl *ctrl) +{ + if (ctrl && ctrl->ops && ctrl->ops->disable) + return ctrl->ops->disable(ctrl); + + return -EINVAL; +} + +/** + * i3c_slave_ctrl_alloc_request() - Alloc an I3C transfer + * @ctrl: I3C slave controller device + * gfp_flags: additional gfp flags used when allocating the buffers + * + * Returns: Zero for success, or an error code in case of failure + */ +static inline struct i3c_request * +i3c_slave_ctrl_alloc_request(struct i3c_slave_ctrl *ctrl, gfp_t gfp_flags) +{ + struct i3c_request *req = NULL; + + if (ctrl && ctrl->ops && ctrl->ops->alloc_request) + req = ctrl->ops->alloc_request(ctrl, gfp_flags); + else + req = kzalloc(sizeof(*req), gfp_flags); + + if (req) + req->ctrl = ctrl; + + return req; +} + +/** + * i3c_slave_ctrl_free_request() - Free an I3C transfer + * @ctrl: I3C slave controller device + * + * Returns: Zero for success, or an error code in case of failure + */ +static inline void +i3c_slave_ctrl_free_request(struct i3c_request *req) +{ + struct i3c_slave_ctrl *ctrl; + + if (!req) + return; + + ctrl = req->ctrl; + if (ctrl && ctrl->ops && ctrl->ops->free_request) + ctrl->ops->free_request(req); + else + kfree(req); +} + +/** + * i3c_slave_ctrl_queue() - Queue an I3C transfer + * @ctrl: I3C slave controller device + * gfp_flags: additional gfp flags used when allocating the buffers + * + * Returns: Zero for success, or an error code in case of failure + */ +static inline int +i3c_slave_ctrl_queue(struct i3c_request *req, gfp_t gfp_flags) +{ + struct i3c_slave_ctrl *ctrl; + int ret = -EINVAL; + + if (!req) + return -EINVAL; + + ctrl = req->ctrl; + + req->actual = 0; + req->status = 0; + if (ctrl && ctrl->ops && ctrl->ops->queue) + ret = ctrl->ops->queue(req, gfp_flags); + + return ret; +} + +/** + * i3c_slave_ctrl_dequeue() - Dequeue an I3C transfer + * @ctrl: I3C slave controller device + * + * Returns: Zero for success, or an error code in case of failure + */ +static inline int +i3c_slave_ctrl_dequeue(struct i3c_request *req) +{ + struct i3c_slave_ctrl *ctrl; + int ret = -EINVAL; + + if (!req) + return -EINVAL; + + ctrl = req->ctrl; + if (ctrl && ctrl->ops && ctrl->ops->dequeue) + ret = ctrl->ops->dequeue(req); + + return ret; +} + +/** + * i3c_slave_ctrl_fifo_status() - Get controller FIFO status + * @ctrl: I3C slave controller device + * @tx: 1: Slave to master, 0: master to slave + * + * Returns: How much data in FIFO + */ +static inline int +i3c_slave_ctrl_fifo_status(struct i3c_slave_ctrl *ctrl, bool tx) +{ + if (ctrl && ctrl->ops && ctrl->ops->fifo_status) + return ctrl->ops->fifo_status(ctrl, tx); + + return 0; +} + +/** + * i3c_slave_ctrl_fifo_flush() - Flush controller FIFO + * @ctrl: I3C slave controller device + * @tx: 1: Slave to master, 0: master to slave + * + */ +static inline void +i3c_slave_ctrl_fifo_flush(struct i3c_slave_ctrl *ctrl, bool tx) +{ + if (ctrl && ctrl->ops && ctrl->ops->fifo_flush) + return ctrl->ops->fifo_flush(ctrl, tx); +} + +/** + * i3c_slave_ctrl_get_features() - Get controller supported features + * @ctrl: I3C slave controller device + * + * Returns: The pointer to struct i3c_slave_ctrl_features + */ +static inline const struct i3c_slave_ctrl_features* +i3c_slave_ctrl_get_features(struct i3c_slave_ctrl *ctrl) +{ + if (ctrl && ctrl->ops && ctrl->ops->get_features) + return ctrl->ops->get_features(ctrl); + + return NULL; +} + +#define to_i3c_slave_ctrl(device) container_of((device), struct i3c_slave_ctrl, dev) + +#define to_i3c_slave_func(func_dev) container_of((func_dev), struct i3c_slave_func, dev) +#define to_i3c_slave_func_driver(drv) (container_of((drv), struct i3c_slave_func_driver, driver)) + +#define i3c_slave_ctrl_create(dev, ops) \ + __i3c_slave_ctrl_create((dev), (ops), THIS_MODULE) +#define devm_i3c_slave_ctrl_create(dev, ops) \ + __devm_i3c_slave_ctrl_create((dev), (ops), THIS_MODULE) + +struct i3c_slave_ctrl * +__devm_i3c_slave_ctrl_create(struct device *dev, const struct i3c_slave_ctrl_ops *ops, + struct module *owner); +struct i3c_slave_ctrl * +__i3c_slave_ctrl_create(struct device *dev, const struct i3c_slave_ctrl_ops *ops, + struct module *owner); + +void devm_i3c_slave_ctrl_destroy(struct device *dev, struct i3c_slave_ctrl *epc); +void i3c_slave_ctrl_destroy(struct i3c_slave_ctrl *epc); + + +int i3c_slave_ctrl_add_func(struct i3c_slave_ctrl *ctrl, struct i3c_slave_func *func); +void i3c_slave_ctrl_remove_func(struct i3c_slave_ctrl *ctrl, struct i3c_slave_func *func); + +struct config_group *i3c_slave_cfs_add_ctrl_group(struct i3c_slave_ctrl *ctrl); + + +void i3c_slave_cfs_remove_ctrl_group(struct config_group *group); +struct config_group *i3c_slave_cfs_add_func_group(const char *name); +void i3c_slave_cfs_remove_func_group(struct config_group *group); +struct i3c_slave_ctrl *i3c_slave_ctrl_get(const char *name); +void i3c_slave_ctrl_put(struct i3c_slave_ctrl *ctrl); + +int i3c_slave_func_bind(struct i3c_slave_func *func); +void i3c_slave_func_unbind(struct i3c_slave_func *func); +struct i3c_slave_func *i3c_slave_func_create(const char *drv_name, const char *name); + +#define i3c_slave_func_register_driver(drv) \ + __i3c_slave_func_register_driver(drv, THIS_MODULE) + +int __i3c_slave_func_register_driver(struct i3c_slave_func_driver *drv, struct module *owner); +void i3c_slave_func_unregister_driver(struct i3c_slave_func_driver *drv); + +#define DECLARE_I3C_SLAVE_FUNC(_name, _probe, _remove, _ops) \ + static struct i3c_slave_func_driver _name ## i3c_func = { \ + .driver.name = __stringify(_name), \ + .owner = THIS_MODULE, \ + .probe = _probe, \ + .remove = _remove, \ + .ops = _ops \ + }; \ + MODULE_ALIAS("i3cfunc:"__stringify(_name)) + +#define DECLARE_I3C_SLAVE_INIT(_name, _probe, _remove, _ops) \ + DECLARE_I3C_SLAVE_FUNC(_name, _probe, _remove, _ops); \ + static int __init _name ## mod_init(void) \ + { \ + return i3c_slave_func_register_driver(&_name ## i3c_func); \ + } \ + static void __exit _name ## mod_exit(void) \ + { \ + i3c_slave_func_unregister_driver(&_name ## i3c_func); \ + } \ + module_init(_name ## mod_init); \ + module_exit(_name ## mod_exit) + +#endif + + From patchwork Tue Sep 5 21:38:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Li X-Patchwork-Id: 13375088 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 36CBECA1008 for ; Tue, 5 Sep 2023 21:39:28 +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:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=QM8Pn7ptlkK2n3z/6wONvVIC3ChNjMNl40EMlK6FmfM=; b=vF2wiSH3IfqXP+ q/sS+ilL+EfNiNyDEqhjln/FCWLpigwl2GGO3i4cdTzQxINmNNoIjHq0fupRByR2nA9lCUUsgz6ix W4nvH9Y3KE86lwLxdxuHuTgrMO/Pd5MybQ6v0axAalJYBXvbQyWBTCMABdtYzdmR/y1iJAJJSdX9h UqJWvIn3e+08N/PhRHQqQdPF8NN3zTdtHBXMyrSzUsXY2J18Fe+St8rYQ821p0m4jHA7rbhL4oH4B YCj/pWCOhP09jC6Q5iDv99uxoyTMmQwHl+0F7F275Bj+kbe1ar2Gzm2we6JMnT+MUWIAAM8MPrB4c 7580nsWxqOOn7OO7X8rQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qddlf-006lo4-1j; Tue, 05 Sep 2023 21:39:27 +0000 Received: from mail-db3eur04on061b.outbound.protection.outlook.com ([2a01:111:f400:fe0c::61b] helo=EUR04-DB3-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qddlb-006lfI-1C for linux-i3c@lists.infradead.org; Tue, 05 Sep 2023 21:39:25 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=hc80I5Ps3yXcOSKva6rA2S01cjK5KXlU0p3QwPSB+XbSeECiXYPkn8gYwfa8+nla4pMaQLOP0EdrBd5MnsVLfzruLuntQ89aVQca8rcJsdswF5k02VTjrjTG53eXjhdLNsg37UPmomT5uLflwe2vLAlCuoa10CKUHBMSRLjE5v1eLok4WN4Go/xNrWgzS7kmBaxvnBVwikfhCs5YDh7267UEMPpVThXTwN44iDOtT3j7UqE6NQdMNMSONadABj7us81C4G22aDdydeOgle/zujUjdOpHAW1Gsfw/pAeIqkJFE/DryF/lpvzOJMlPWsii14N7yfNyOurWuR2KJt1ALA== 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=IE9x/i/BtqK61JFzQblLOpV/r/FT6UyuGUCJUR8vRsQ=; b=NYMBUtjWEVAQc4zKOr5M+L4fFN30FCkCJHDCZffYHNr5EbRBuaPtTUhR8NrL3s6eDpjctobXX0dMqm9cGLdmBFl3lfRGRQpnW/aR0TZsiC6yz2eeoNpJ32gU/od0tXyO4Rf9q74Veu0qWsgLKcqlkn6a3h3yvxk8NJXdUva5SbDQEmmZZEPNvfBulkBgmvlWT3o22COPvK0RRjEeYO5C/GP5mLQtA0GEXOV5Xby37Wk8dkKQKs+EqRQSnn8MZ/M8mfCbS8jv/KpxMABcwDmq31iqnDpJjXnjkFfRvQYEOvoWbhFAhZwUZpWhjKUT5DIOvJeYVzfHB4lSHJXrsUucXQ== 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=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=IE9x/i/BtqK61JFzQblLOpV/r/FT6UyuGUCJUR8vRsQ=; b=cvuivyjid9d+RiWsZMq76JSkhSvkTNKuUOnGZfHeJxjxsb/Niwa9RBpbx2uMPBVJyQ7nB+Rgemltfj8tI7KchHGhZA00hPZHlg70EKwmqyPIxk3ulGktRpRjXdesCqEtjA0XRsUjzRL74P7BQupXxAQU0NLmgTG+hV0hsP3GxCk= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from AM6PR04MB4838.eurprd04.prod.outlook.com (2603:10a6:20b:4::16) by PAXPR04MB9256.eurprd04.prod.outlook.com (2603:10a6:102:2ba::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6745.34; Tue, 5 Sep 2023 21:39:14 +0000 Received: from AM6PR04MB4838.eurprd04.prod.outlook.com ([fe80::aa90:117d:c1d0:346a]) by AM6PR04MB4838.eurprd04.prod.outlook.com ([fe80::aa90:117d:c1d0:346a%3]) with mapi id 15.20.6745.030; Tue, 5 Sep 2023 21:39:14 +0000 From: Frank Li To: miquel.raynal@bootlin.com Cc: Frank.Li@nxp.com, alexandre.belloni@bootlin.com, conor.culhane@silvaco.com, imx@lists.linux.dev, linux-i3c@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 6/9] i3c: slave: add svc slave controller support Date: Tue, 5 Sep 2023 17:38:39 -0400 Message-Id: <20230905213842.3035779-7-Frank.Li@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230905213842.3035779-1-Frank.Li@nxp.com> References: <20230905213842.3035779-1-Frank.Li@nxp.com> X-ClientProxiedBy: SJ0PR03CA0215.namprd03.prod.outlook.com (2603:10b6:a03:39f::10) To AM6PR04MB4838.eurprd04.prod.outlook.com (2603:10a6:20b:4::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AM6PR04MB4838:EE_|PAXPR04MB9256:EE_ X-MS-Office365-Filtering-Correlation-Id: e14e45f8-3068-4976-4632-08dbae588c86 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: ut3gnDzcOIlEdANwJ+7iawAYO7tvG3sQAJCgA0gJHY0W+WF3QTuwV9v7/wDpy9GxsGo4A/UaaV2Z8AFEERBgNWdAE8QNEP2RE389d2FINTargt4nsQON5Nwh76rVBqynwxzKgbq0FszR7JLcJh5gJxw2af0lVJyxyv6lMsL8MFhHaV/7A1RAPNWnq+ewypfiU+oXe2t0vjYJ57G6WBIjohH9cQkrTaSS21+rXY3zWAqaeYkXTqhWgJecQKebmV1MpXPQ+HExnmZK9/jkEH5KzPzrXYcaVUDK28zPyUuVACvI/SQCAMIAVjSMO99sP0mhDv+2lDa2jigWw8jri6fg7jGV6zaZW5/MzhOM+NrDSOjZX+ToMx2/ApHV4HMIgOnBk4Z/qwDXFdZrHGBjJwwpbol4rG3WRan0JAYNgmuKeEydUBut/l18vbbfW8cDxJW+Bnyr2FIHrlYuXcTDQFdVJS3YryJ5UkmXOFBRBTjs5Q+x/zWpdbnLf3zuKq2yjonuo6vPtP2YTK5a+n0pBSKEy7lvKJ7YUX8kiZZ9k70NwJDRd7I+KtW7m35fUcs8FJwiqk98nPsw1hsYskdPYZqZ8H8dex2m8adx5bMayuXE3oaLS9M8EC3Qnbwd7xYVtWOt X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:AM6PR04MB4838.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(396003)(376002)(39860400002)(366004)(346002)(136003)(186009)(1800799009)(451199024)(2906002)(30864003)(83380400001)(6486002)(52116002)(6506007)(6916009)(316002)(66946007)(66556008)(66476007)(478600001)(26005)(6666004)(5660300002)(1076003)(41300700001)(8676002)(8936002)(6512007)(2616005)(4326008)(36756003)(38100700002)(38350700002)(86362001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: t6qPLjB3nYAfA0LLUuMR6SAtxKfJ++V/M2wBhg1bBJj+Yw6QcLETwJfhvKtrVGOvr2LdFszzA4U/XN3yiGZxFQiR7d3Qk4aqhaLRYm0nTfuiHJxL8d9juM430lxZvQH7a4RxP5OBjco5MmrwBvDbw00rqnxY0I9JEnfgW9DC5X/0PpJUiyzTEXmpr6oQbA8wADlDPd7KdKZ6vvfZ1yJ3LESWX8OM+ZCJSvD2nrYvs3goafpwmsuMsYoYUeqrqKFBYAExO3xr0bPEGWbqz8cZAyLumltdJufDEb8g3gY7efbOa0IQ2jaE4kjZiqwe0PGR8ivoFVat5Tzv+UHCa3Eroq3f368G1Vl5EXmqt5A9kVj4TtjAuIvfgLqza8YGd3rfUrG8lp0PGd/bmghigrwka+I9EQxPS0oeeW+BUcpVAHTYQly9rhXkNyAqOFRvzX6vge2Na/AOh3LVCAYnfQ8vsIqVNV3GPep/tqgXJHFBXJv9xa2vBNr7k8gI268tIwUC8Nz/ksxygoU3GO2dMrR8UyHd3igO2PwBoQdaTZNp8siduevS0xD/Z7Fz+Lwhb/43N8eArhqeTV3hZD4K0dUT5ttwCLlYsoY1re8tnomwQei5NrsPMTH0mdaUMzCI3wtgRIL0Y8LETcc1oWAuHb2SXCHztspVJa1fJfowzFGEiJ6WLSWPlvT36JfrsxouBc/1WhXExe+szdml96issxkH5jbUYKLXBduwG9p+TnSNJNuYPuMxcLBir2GPzR+NpSDJ7/DtTUjZWAzKTXRkb4sH7ARM609RP4WV6i2bCAbMW92abss0CjVnbPjArgSEOAYWBigDGtRvLTQpXgLNWVClLDB7ZNQblmONd38L+oKo3rvI4/zKpEqyk5yfNNffFWJnIZJ7fLov2c6xwyV6yNlURkb42UUl+63E0BnE5B8gHUaGeXqI6ePHX3VmXyWDvELegTN4fGhsHO7WGV/5YmtKkkqUq311Gq4UrYSaesn8dTriDTjNaNf2aqdevxYQTgZ8onlA7/2Jnl79tioeSBXi9KT3OSvjG7ora+MqYA/UJg1GExC4dVA3t9OLGGGxOiMgHaghU9+SiT5YdbqQmiioswgbDlKoUB9owVlZVN5BP0JQqURS9RVZcskTuMYzpmZg1z1o6yY7vB/ztMRnOVXjY0M0StrABA/1oMYOfnrTO6+2B3GyWKYX7Ylp0VDPLrLQt+Kty9kaGeHUx+rvByTpv2apxZPbfYFWLlaRgVOPoRZrsSRCn3BMIoR4+81WJKFQb4IYrHYZ8GCBWxMPVZv0sm6nbfCHuezRHWKmxeLxOCVPSVqAjltpBSBA0BWfC+eDN6yIovL0vzWHjkA6l3e47AyBam+sJ2pLV3CujDivrgaZUjmHP4HlS3HxoCTOSeNPTRmirxsB8e2B9gKGGuZpDG4GOEOXSI+s3qEjt483Dn4640VmToZaxZY08/JVQKGmN3AhiVolzxMByQsFV+zaVefTvzQ7gXjinZ/OKyoLIFBgMoI/hA4ZeGh2aI3yxdDjl+XQz1S5r7qa3cjE6kzaUl/6p9OeQ1O+JMjSp4Tdec6YRIbyrNmEeUGWMjBFWWZu X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: e14e45f8-3068-4976-4632-08dbae588c86 X-MS-Exchange-CrossTenant-AuthSource: AM6PR04MB4838.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Sep 2023 21:39:14.2584 (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: mpdfp1GUwyyz492Q98SQWj4p4nso6v30gY8QKorT6pUtMoPkU1VXUymlHPC9T2PllB207tgOPWbobS5/lfX8ow== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB9256 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230905_143923_411870_42CC7573 X-CRM114-Status: GOOD ( 18.07 ) 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 Add Silvaco I3C slave controller support Signed-off-by: Frank Li --- drivers/i3c/Makefile | 1 + drivers/i3c/slave/Kconfig | 9 + drivers/i3c/slave/Makefile | 4 + drivers/i3c/slave/svc-i3c-slave.c | 600 ++++++++++++++++++++++++++++++ 4 files changed, 614 insertions(+) create mode 100644 drivers/i3c/slave/Kconfig create mode 100644 drivers/i3c/slave/Makefile create mode 100644 drivers/i3c/slave/svc-i3c-slave.c diff --git a/drivers/i3c/Makefile b/drivers/i3c/Makefile index 6407ddec3a4a9..ef1acbe13fe60 100644 --- a/drivers/i3c/Makefile +++ b/drivers/i3c/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_I3C) += i3c.o obj-$(CONFIG_I3C) += master/ obj-$(CONFIG_I3C_SLAVE) += slave.o obj-$(CONFIG_I3C_SLAVE_CONFIGFS) += i3c-cfs.o +obj-$(CONFIG_I3C_SLAVE) += slave/ diff --git a/drivers/i3c/slave/Kconfig b/drivers/i3c/slave/Kconfig new file mode 100644 index 0000000000000..e385dbdea193b --- /dev/null +++ b/drivers/i3c/slave/Kconfig @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 + +config I3C_SLAVE_CTRL_SVC + tristate "Silvaco I3C Dual-Role Slave driver" + depends on I3C + depends on HAS_IOMEM + depends on !(ALPHA || PARISC) + help + Support for Silvaco I3C Dual-Role Slave Controller. diff --git a/drivers/i3c/slave/Makefile b/drivers/i3c/slave/Makefile new file mode 100644 index 0000000000000..612be24536311 --- /dev/null +++ b/drivers/i3c/slave/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-${CONFIG_I3C_SLAVE_CTRL_SVC} += svc-i3c-slave.o + diff --git a/drivers/i3c/slave/svc-i3c-slave.c b/drivers/i3c/slave/svc-i3c-slave.c new file mode 100644 index 0000000000000..01824913bfbc4 --- /dev/null +++ b/drivers/i3c/slave/svc-i3c-slave.c @@ -0,0 +1,600 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2023 NXP. + * + * Author: Frank Li + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum i3c_clks { + PCLK, + FCLK, + SCLK, + MAXCLK, +}; + +struct svc_i3c_slave { + struct device *dev; + void __iomem *regs; + int irq; + struct clk_bulk_data clks[MAXCLK]; + + struct list_head txq; + spinlock_t txq_lock; + struct list_head rxq; + spinlock_t rxq_lock; + struct list_head cq; + spinlock_t cq_lock; + + struct work_struct work; + struct workqueue_struct *workqueue; + + struct i3c_slave_ctrl_features features; +}; + +#define I3C_SCONFIG 0x4 +#define I3C_SCONFIG_SLVENA_MASK BIT(0) +#define I3C_SCONFIG_SADDR_MASK GENMASK(31, 25) + +#define I3C_SSTATUS 0x8 +#define I3C_SSTATUS_STOP_MASK BIT(10) +#define I3C_SSTATUS_RX_PEND_MASK BIT(11) +#define I3C_SSTATUS_TXNOTFULL_MASK BIT(12) + +#define I3C_SCTRL 0xc +#define I3C_SCTRL_EVENT_MASK GENMASK(1, 0) +#define I3C_SCTRL_EVENT_IBI 0x1 +#define I3C_SCTRL_EXTDATA_MASK BIT(3) +#define I3C_SCTRL_IBIDATA_MASK GENMASK(15, 8) + + +#define I3C_SINTSET 0x10 +#define I3C_SINTCLR 0x14 +#define I3C_SINT_START BIT(8) +#define I3C_SINT_MATCHED BIT(9) +#define I3C_SINT_STOP BIT(10) +#define I3C_SINT_RXPEND BIT(11) +#define I3C_SINT_TXSEND BIT(12) +#define I3C_SINT_DACHG BIT(13) +#define I3C_SINT_CCC BIT(14) +#define I3C_SINT_ERRWARN BIT(15) +#define I3C_SINT_DDRMAATCHED BIT(16) +#define I3C_SINT_CHANDLED BIT(17) +#define I3C_SINT_EVENT BIT(18) +#define I3C_SINT_SLVRST BIT(19) + +#define I3C_SDATACTRL 0x2c +#define I3C_SDATACTRL_RXEMPTY_MASK BIT(31) +#define I3C_SDATACTRL_TXFULL_MASK BIT(30) +#define I3C_SDATACTRL_FLUSHFB_MASK BIT(1) +#define I3C_SDATACTRL_FLUSHTB_MASK BIT(0) + +#define I3C_SWDATAB 0x30 +#define I3C_SWDATAE 0x34 +#define I3C_SRDATAB 0x40 + +#define I3C_SCAPABILITIES 0x60 +#define I3C_SCAPABILITIES_FIFOTX_MASK GENMASK(27, 26) +#define I3C_SCAPABILITIES_FIFORX_MASK GENMASK(29, 28) + +#define I3C_SMAXLIMITS 0x68 +#define I3C_SMAXLIMITS_MAXRD_MASK GENMASK(11, 0) +#define I3C_SMAXLIMITS_MAXWR_MASK GENMASK(27, 16) + +#define I3C_SIDPARTNO 0x6c + +#define I3C_SIDEXT 0x70 +#define I3C_SIDEXT_BCR_MASK GENMASK(23, 16) +#define I3C_SIDEXT_DCR_MASK GENMASK(15, 8) +#define I3C_SVENDORID 0x74 + + +#define I3C_IBIEXT1 0x140 +#define I3C_IBIEXT1_CNT_MASK GEN_MASK(2, 0) +#define I3C_IBIEXT1_MAX_MASK GEN_MASK(4, 6) +#define I3C_IBIEXT1_EXT1_SHIFT 8 +#define I3C_IBIEXT1_EXT2_SHIFT 16 +#define I3C_IBIEXT1_EXT3_SHIFT 24 + +#define I3C_IBIEXT2 0x144 +#define I3C_IBIEXT2_EXT4_SHIFT 0 +#define I3C_IBIEXT2_EXT5_SHIFT 8 +#define I3C_IBIEXT2_EXT6_SHIFT 16 +#define I3C_IBIEXT2_EXT7_SHIFT 24 + +static int svc_i3c_slave_enable(struct i3c_slave_ctrl *ctrl) +{ + struct svc_i3c_slave *svc; + u32 val; + + svc = dev_get_drvdata(&ctrl->dev); + + val = readl_relaxed(svc->regs + I3C_SCONFIG); + val |= I3C_SCONFIG_SLVENA_MASK; + writel_relaxed(val, svc->regs + I3C_SCONFIG); + + return 0; +} + +static int svc_i3c_slave_disable(struct i3c_slave_ctrl *ctrl) +{ + struct svc_i3c_slave *svc; + u32 val; + + svc = dev_get_drvdata(&ctrl->dev); + + val = readl_relaxed(svc->regs + I3C_SCONFIG); + val &= ~I3C_SCONFIG_SLVENA_MASK; + writel_relaxed(val, svc->regs + I3C_SCONFIG); + + return 0; +} + +static int svc_i3c_slave_set_config(struct i3c_slave_ctrl *ctrl, struct i3c_slave_func *func) +{ + struct svc_i3c_slave *svc; + u32 val; + u32 wm, rm; + + svc = dev_get_drvdata(&ctrl->dev); + + if (func->static_addr > 0x7F) + return -EINVAL; + + val = readl_relaxed(svc->regs + I3C_SCONFIG); + val &= ~I3C_SCONFIG_SLVENA_MASK; + val |= FIELD_PREP(I3C_SCONFIG_SADDR_MASK, func->static_addr); + writel_relaxed(val, svc->regs + I3C_SCONFIG); + + if (func->part_id) + writel_relaxed((func->part_id << 16) | + ((func->instance_id << 12) & GENMASK(15, 12)) | + (func->ext_id & GENMASK(11, 0)), svc->regs + I3C_SIDPARTNO); + + writel_relaxed(FIELD_PREP(I3C_SIDEXT_BCR_MASK, func->bcr) | + FIELD_PREP(I3C_SIDEXT_DCR_MASK, func->dcr), + svc->regs + I3C_SIDEXT); + + wm = func->max_write_len == 0 ? + FIELD_GET(I3C_SMAXLIMITS_MAXWR_MASK, I3C_SMAXLIMITS_MAXWR_MASK) : func->max_write_len; + + wm = max_t(u32, val, 8); + + rm = func->max_read_len == 0 ? + FIELD_GET(I3C_SMAXLIMITS_MAXRD_MASK, I3C_SMAXLIMITS_MAXRD_MASK) : func->max_read_len; + rm = max_t(u32, val, 16); + + val = FIELD_PREP(I3C_SMAXLIMITS_MAXRD_MASK, rm) | FIELD_PREP(I3C_SMAXLIMITS_MAXWR_MASK, wm); + writel_relaxed(val, svc->regs + I3C_SMAXLIMITS); + + writel_relaxed(func->vendor_id, svc->regs + I3C_SVENDORID); + return 0; +} + +const struct i3c_slave_ctrl_features *svc_i3c_get_features(struct i3c_slave_ctrl *ctrl) +{ + struct svc_i3c_slave *svc; + + svc = dev_get_drvdata(&ctrl->dev); + + if (!svc) + return NULL; + + return &svc->features; +} + +static int svc_i3c_slave_queue(struct i3c_request *req, gfp_t) +{ + struct svc_i3c_slave *svc; + struct list_head *q; + unsigned long flags; + spinlock_t *lk; + + svc = dev_get_drvdata(&req->ctrl->dev); + if (!svc) + return -EINVAL; + + if (req->tx) { + q = &svc->txq; + lk = &svc->txq_lock; + } else { + q = &svc->rxq; + lk = &svc->rxq_lock; + } + + spin_lock_irqsave(lk, flags); + list_add_tail(&req->list, q); + spin_unlock_irqrestore(lk, flags); + + if (req->tx) + writel_relaxed(I3C_SINT_TXSEND, svc->regs + I3C_SINTSET); + else + writel_relaxed(I3C_SINT_RXPEND, svc->regs + I3C_SINTSET); + + return 0; +} + +static int svc_i3c_dequeue(struct i3c_request *req) +{ + struct svc_i3c_slave *svc; + unsigned long flags; + spinlock_t *lk; + + svc = dev_get_drvdata(&req->ctrl->dev); + if (!svc) + return -EINVAL; + + if (req->tx) + lk = &svc->txq_lock; + else + lk = &svc->rxq_lock; + + spin_lock_irqsave(lk, flags); + list_del(&req->list); + spin_unlock_irqrestore(lk, flags); + + return 0; +} + +static void svc_i3c_slave_fifo_flush(struct i3c_slave_ctrl *ctrl, bool tx) +{ + struct svc_i3c_slave *svc; + u32 val; + + svc = dev_get_drvdata(&ctrl->dev); + + val = readl_relaxed(svc->regs + I3C_SDATACTRL); + + val |= tx ? I3C_SDATACTRL_FLUSHTB_MASK : I3C_SDATACTRL_FLUSHFB_MASK; + + writel_relaxed(val, svc->regs + I3C_SDATACTRL); +} + +static int +svc_i3c_slave_raise_ibi(struct i3c_slave_ctrl *ctrl, void *p, u8 size) +{ + struct svc_i3c_slave *svc; + u8 *ibidata = p; + u32 ext1 = 0, ext2 = 0; + u32 val; + int ret; + + svc = dev_get_drvdata(&ctrl->dev); + + if (size && !p) + return -EINVAL; + + if (size > 8) + return -EINVAL; + + ret = readl_relaxed_poll_timeout(svc->regs + I3C_SCTRL, val, + !(val & I3C_SCTRL_EVENT_MASK), 0, 10000); + if (ret) { + dev_err(&ctrl->dev, "Timeout when polling for NO event pending"); + return -ENAVAIL; + } + + val &= ~I3C_SCTRL_EVENT_MASK | I3C_SCTRL_IBIDATA_MASK; + val |= FIELD_PREP(I3C_SCTRL_EVENT_MASK, I3C_SCTRL_EVENT_IBI); + + if (size) { + val |= FIELD_PREP(I3C_SCTRL_IBIDATA_MASK, *ibidata); + ibidata++; + + if (size > 1) + val |= I3C_SCTRL_EXTDATA_MASK; + + size--; + if (size > 0) { + ext1 |= (size + 2); + ext1 |= (*ibidata++) << I3C_IBIEXT1_EXT1_SHIFT; + size--; + } + + if (size > 0) { + ext1 |= (*ibidata++) << I3C_IBIEXT1_EXT2_SHIFT; + size--; + } + + if (size > 0) { + ext1 |= (*ibidata++) << I3C_IBIEXT1_EXT3_SHIFT; + size--; + } + + writel_relaxed(ext1, svc->regs + I3C_IBIEXT1); + + if (size > 0) { + ext2 |= (*ibidata++) << I3C_IBIEXT2_EXT4_SHIFT; + size--; + } + + if (size > 0) { + ext2 |= (*ibidata++) << I3C_IBIEXT2_EXT5_SHIFT; + size--; + } + + if (size > 0) { + ext2 |= (*ibidata++) << I3C_IBIEXT2_EXT6_SHIFT; + size--; + } + + if (size > 0) { + ext2 |= (*ibidata++) << I3C_IBIEXT2_EXT7_SHIFT; + size--; + } + + writeb_relaxed(ext2, svc->regs + I3C_IBIEXT2); + } + + /* Issue IBI*/ + writel_relaxed(val, svc->regs + I3C_SCTRL); + + ret = readl_relaxed_poll_timeout(svc->regs + I3C_SCTRL, val, + !(val & I3C_SCTRL_EVENT_MASK), 0, 10000); + if (ret) { + dev_err(&ctrl->dev, "Timeout when polling for IBI finish\n"); + return -ENAVAIL; + } + + return 0; +} + +static void svc_i3c_slave_complete(struct work_struct *work) +{ + struct svc_i3c_slave *svc = container_of(work, struct svc_i3c_slave, work); + struct i3c_request *req; + unsigned long flags; + + spin_lock_irqsave(&svc->cq_lock, flags); + while (!list_empty(&svc->cq)) { + req = list_first_entry(&svc->cq, struct i3c_request, list); + list_del(&req->list); + spin_unlock_irqrestore(&svc->cq_lock, flags); + req->complete(req); + + spin_lock_irqsave(&svc->cq_lock, flags); + } + spin_unlock_irqrestore(&svc->cq_lock, flags); +} + +static irqreturn_t svc_i3c_slave_irq_handler(int irq, void *dev_id) +{ + struct i3c_request *req, *complete = NULL; + struct svc_i3c_slave *svc = dev_id; + unsigned long flags; + u32 statusFlags; + + statusFlags = readl(svc->regs + I3C_SSTATUS); + writel(statusFlags, svc->regs + I3C_SSTATUS); + + if (statusFlags & I3C_SSTATUS_RX_PEND_MASK) { + spin_lock_irqsave(&svc->rxq_lock, flags); + req = list_first_entry_or_null(&svc->rxq, struct i3c_request, list); + + if (!req) { + writel_relaxed(I3C_SINT_RXPEND, svc->regs + I3C_SINTCLR); + } else { + while (!(readl_relaxed(svc->regs + I3C_SDATACTRL) & + I3C_SDATACTRL_RXEMPTY_MASK)) { + + *(u8 *)(req->buf + req->actual) = + readl_relaxed(svc->regs + I3C_SRDATAB); + req->actual++; + + if (req->actual == req->length) { + complete = req; + list_del(&req->list); + break; + } + } + + if (req->actual != req->length && (statusFlags & I3C_SSTATUS_STOP_MASK)) { + complete = req; + list_del(&req->list); + } + } + spin_unlock_irqrestore(&svc->rxq_lock, flags); + + if (complete) { + spin_lock_irqsave(&svc->cq_lock, flags); + list_add_tail(&complete->list, &svc->cq); + spin_unlock_irqrestore(&svc->cq_lock, flags); + queue_work(svc->workqueue, &svc->work); + complete = NULL; + } + } + + if (statusFlags & I3C_SSTATUS_TXNOTFULL_MASK) { + + complete = NULL; + spin_lock_irqsave(&svc->txq_lock, flags); + req = list_first_entry_or_null(&svc->txq, struct i3c_request, list); + if (!req) { + writel_relaxed(I3C_SINT_TXSEND, svc->regs + I3C_SINTCLR); + } else { + while (!(readl_relaxed(svc->regs + I3C_SDATACTRL) + & I3C_SDATACTRL_TXFULL_MASK)) { + + if (req->actual + 1 == req->length) + writel_relaxed(*(u8 *)(req->buf + req->actual), + svc->regs + I3C_SWDATAE); + else + writel_relaxed(*(u8 *)(req->buf + req->actual), + svc->regs + I3C_SWDATAB); + + req->actual++; + + if (req->actual == req->length) { + list_del(&req->list); + complete = req; + break; + } + } + } + spin_unlock_irqrestore(&svc->txq_lock, flags); + if (complete) + complete->complete(complete); + } + + return IRQ_HANDLED; +} + +static void svc_i3c_cancel_all_reqs(struct i3c_slave_ctrl *ctrl, bool tx) +{ + struct svc_i3c_slave *svc; + struct i3c_request *req; + struct list_head *q; + unsigned long flags; + spinlock_t *lk; + + svc = dev_get_drvdata(&ctrl->dev); + if (!svc) + return; + + if (tx) { + q = &svc->txq; + lk = &svc->txq_lock; + } else { + q = &svc->rxq; + lk = &svc->rxq_lock; + } + + spin_lock_irqsave(lk, flags); + while (list_empty(q)) { + req = list_first_entry(q, struct i3c_request, list); + list_del(&req->list); + spin_unlock_irqrestore(lk, flags); + + req->status = I3C_REQUEST_CANCEL; + req->complete(req); + spin_lock_irqsave(lk, flags); + } + spin_unlock_irqrestore(lk, flags); +} + +static struct i3c_slave_ctrl_ops svc_i3c_slave_ops = { + .set_config = svc_i3c_slave_set_config, + .enable = svc_i3c_slave_enable, + .disable = svc_i3c_slave_disable, + .queue = svc_i3c_slave_queue, + .dequeue = svc_i3c_dequeue, + .raise_ibi = svc_i3c_slave_raise_ibi, + .fifo_flush = svc_i3c_slave_fifo_flush, + .cancel_all_reqs = svc_i3c_cancel_all_reqs, + .get_features = svc_i3c_get_features, +}; + +static int svc_i3c_slave_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct i3c_slave_ctrl *slave; + struct svc_i3c_slave *svc; + int ret; + u32 val; + + svc = devm_kzalloc(dev, sizeof(*svc), GFP_KERNEL); + if (!svc) + return -ENOMEM; + + svc->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(svc->regs)) + return PTR_ERR(svc->regs); + + svc->clks[PCLK].id = "pclk"; + svc->clks[FCLK].id = "fast_clk"; + svc->clks[SCLK].id = "slow_clk"; + + ret = devm_clk_bulk_get(dev, MAXCLK, svc->clks); + if (ret < 0) { + dev_err(dev, "fail get clks: %d\n", ret); + return ret; + } + + ret = clk_bulk_prepare_enable(MAXCLK, svc->clks); + if (ret < 0) { + dev_err(dev, "fail enable clks: %d\n", ret); + return ret; + } + + svc->irq = platform_get_irq(pdev, 0); + if (svc->irq < 0) + return svc->irq; + + INIT_LIST_HEAD(&svc->txq); + INIT_LIST_HEAD(&svc->rxq); + INIT_LIST_HEAD(&svc->cq); + spin_lock_init(&svc->txq_lock); + spin_lock_init(&svc->rxq_lock); + spin_lock_init(&svc->cq_lock); + + INIT_WORK(&svc->work, svc_i3c_slave_complete); + svc->workqueue = alloc_workqueue("%s-cq", 0, 0, dev_name(dev)); + if (!svc->workqueue) + return -ENOMEM; + + /* Disable all IRQ */ + writel_relaxed(0xFFFFFFFF, svc->regs + I3C_SINTCLR); + + val = readl_relaxed(svc->regs + I3C_SCAPABILITIES); + svc->features.tx_fifo_sz = FIELD_GET(I3C_SCAPABILITIES_FIFOTX_MASK, val); + svc->features.tx_fifo_sz = 2 << svc->features.tx_fifo_sz; + + svc->features.rx_fifo_sz = FIELD_GET(I3C_SCAPABILITIES_FIFORX_MASK, val); + svc->features.rx_fifo_sz = 2 << svc->features.rx_fifo_sz; + + ret = devm_request_irq(dev, svc->irq, svc_i3c_slave_irq_handler, 0, "svc-i3c-irq", svc); + if (ret) + return -ENOENT; + + slave = devm_i3c_slave_ctrl_create(dev, &svc_i3c_slave_ops); + if (!slave) + return -ENOMEM; + + dev_set_drvdata(&slave->dev, svc); + + return 0; +} + +static int svc_i3c_slave_remove(struct platform_device *pdev) +{ + return 0; +} + +static const struct of_device_id svc_i3c_slave_of_match_tbl[] = { + { .compatible = "silvaco,i3c-slave" }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, svc_i3c_slave_of_match_tbl); + +static struct platform_driver svc_i3c_slave = { + .probe = svc_i3c_slave_probe, + .remove = svc_i3c_slave_remove, + .driver = { + .name = "silvaco-i3c-slave", + .of_match_table = svc_i3c_slave_of_match_tbl, + //.pm = &svc_i3c_pm_ops, + }, +}; +module_platform_driver(svc_i3c_slave); + +MODULE_DESCRIPTION("Silvaco dual-role I3C slave driver"); +MODULE_LICENSE("GPL"); From patchwork Tue Sep 5 21:38:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Li X-Patchwork-Id: 13375089 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 3AB5DCA100D for ; Tue, 5 Sep 2023 21:39:30 +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:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=CIEwE8iDRfwrgXDWmDsL1v/GAND5YwaLDeOPnVY9vOA=; b=CZoVZMtoYi5s6Z 3jeVQVO6l9PRJyXtTkO+BRm11fw6fm6aN6kTWY1bMAJwNswRYACscTaZ9Ply83831zehmwTbkCPHa CF6uCFGmAOgF0cHdrw+KK8Vqn6yKcIJp43MmCjQAaQ/Pw8XwzIaLZ+sXaCEqoiJFOSYuRJ4mi7drP cKYnQHONes+pEFHBQe/JsT6PCIMAVSWE4WlbNnCdUUGZeksQuGeJItJURa6fz0w1fDONCoADDMVQb 524egpWYaPWoeh6VEmstcTdP5MpcRm3W4m7CHQ/oIn+9r2T4b0CBG3Zj3MDY4/avu1qW0N8TBij5l zFtVp0SKIseymq8mTbeQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qddlh-006lpd-34; Tue, 05 Sep 2023 21:39:29 +0000 Received: from mail-db3eur04on061b.outbound.protection.outlook.com ([2a01:111:f400:fe0c::61b] helo=EUR04-DB3-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qddle-006lfI-04 for linux-i3c@lists.infradead.org; Tue, 05 Sep 2023 21:39:27 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=ARkJfgFrooAjDoAKYRoYF3E1XxbBQaRkFkfB049ZSbMQcTeXFZYb+11nI9qVCxE6hAU1t16v8x00ZBUr8jnRwO9F2v8vZHRjl5X9ldbP4mXEJkwnMF8K2bqI24ukxJiUTw5hjwa+ZDHHYuV8Zb5Dqj/Q3h4M/l+uSWcB3mY2ZuxZF7JvHypeYSa3RBD+u+bmkq7vvJIYGOej0PFKe9H2DpQsFpqQBLX2unJ3B2I/boIig2Idk9Nn2v+6Bz4L6b2ZVymw0sVr2cCDJN+JxZUnvYS5ejzRU3nYbBgYe1ZCMH9GOMfxDtmiROYB8mmxjdCFZE6hlJz/95EkZSCUdmv2lg== 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=qhAWRTZ9ZJxtjvZDtNLnMvxl6E4HoftWE2I+MAyjVkA=; b=REYX7p55l2cbcWmbkWx8kovoUnYv43BMgSTb1XoA4VYOSz9A4t9TGTbk1G9ImKPZQjKXQC6a8D7mbmMvF1pm5cN4hcA0O3n/m5xV0awWr6WBJS2Ryq0We0UWFZ4LIAZNdQUAnrHBZNZQufndzqM8j89k4gLnkgxITSuxxJYZih4iLlg9UB7d7VgJjMSGnR+BsdjCiuq6HRkc2Ha8c9rpdG5B43aQyJbHOPhvXWzKXVSLBfamTppUDCiWNZL0aWma7Q/r+iaoO03u4hlKWWu/U2s0PGTSVfbAMqdIhLUaCQPHvEEAC+1Kslm5M6EoJsIvd3o5w/iuk4yP5+vgAvmRSw== 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=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=qhAWRTZ9ZJxtjvZDtNLnMvxl6E4HoftWE2I+MAyjVkA=; b=oGEDXsez5HxemAcXAMXlFA3Tw141e9jhunFHwM3JKQsnqXCEHMKK9bQxKwEZtbac2fAGHTP7Yd+mByaOmWr0P7K/J3qzJb8ZKrl9ASq3y+D22xJ12PnuhzzhZnjNUegx71Mg+N21lp/6I86F3KRFZ3JVGx83v8Yc117Azbn8YgY= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from AM6PR04MB4838.eurprd04.prod.outlook.com (2603:10a6:20b:4::16) by PAXPR04MB9256.eurprd04.prod.outlook.com (2603:10a6:102:2ba::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6745.34; Tue, 5 Sep 2023 21:39:16 +0000 Received: from AM6PR04MB4838.eurprd04.prod.outlook.com ([fe80::aa90:117d:c1d0:346a]) by AM6PR04MB4838.eurprd04.prod.outlook.com ([fe80::aa90:117d:c1d0:346a%3]) with mapi id 15.20.6745.030; Tue, 5 Sep 2023 21:39:16 +0000 From: Frank Li To: miquel.raynal@bootlin.com Cc: Frank.Li@nxp.com, alexandre.belloni@bootlin.com, conor.culhane@silvaco.com, imx@lists.linux.dev, linux-i3c@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 7/9] i3c: slave: func: add tty driver Date: Tue, 5 Sep 2023 17:38:40 -0400 Message-Id: <20230905213842.3035779-8-Frank.Li@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230905213842.3035779-1-Frank.Li@nxp.com> References: <20230905213842.3035779-1-Frank.Li@nxp.com> X-ClientProxiedBy: SJ0PR03CA0215.namprd03.prod.outlook.com (2603:10b6:a03:39f::10) To AM6PR04MB4838.eurprd04.prod.outlook.com (2603:10a6:20b:4::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AM6PR04MB4838:EE_|PAXPR04MB9256:EE_ X-MS-Office365-Filtering-Correlation-Id: edf7fabb-6481-402f-44d4-08dbae588dcf X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 329Aw+11HxrovyNPjKaFqNV7D6M9QKtqFLcik0TWqV2B+2HSQbZNpWeqpjEqWiHp4k7E3SZfQjshBGzURiW7xbtsM72tTozz6COHl65oxWt48vyMD1+x01AbQ4sLYQZG0PLTgd63HGo+yPPA1VbvodJEO0cV8JM3qnfedEs53kqcqN+tblUt/EQgPf0xp2Yyn8bNy0XzFSDJwY5uCG1ZrHhUo9Zc2Esky486xEU0wJUaW8UGczWCyZ/GqfDXPTpdE6RX+ZaWJl72LZstRDBouEcSmG/W3jTb5cQq5YMJJlL7kME92sNhDpahJQJZ/ORyyTTXk1f9ZG1i2GINCVNPmgzXRynq5p6uPdl/LmsX4yLi9fi81s5j0jd7d+JSF7dbffJ+BAnuu21HcTw8BJjicLy/yTpacuM93LVfR07V3BlBLqobzSEAtr+2UszjL7mF6WaIzM32+XE6/4TDUdk8txPwBjmXxOiupFSkcVIE/bUuoZ9zOqO6+M81+GCodryrxMtl5g+CIVFitkoSXRuz2xBEu4x+SfQFzY42QhsNyudTwsCCFoLjgGvvNeoRdN3C5YXF3UJZu7izcWm+J2X0lAlxz0V4wLpPeJkX8bRLWsskJJaXC5i1N0TLJ1Ra9/7Q X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:AM6PR04MB4838.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(396003)(376002)(39860400002)(366004)(346002)(136003)(186009)(1800799009)(451199024)(2906002)(83380400001)(6486002)(52116002)(6506007)(6916009)(316002)(66946007)(66556008)(66476007)(478600001)(26005)(6666004)(5660300002)(1076003)(41300700001)(8676002)(8936002)(6512007)(2616005)(4326008)(36756003)(38100700002)(38350700002)(86362001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: SqYxuuQuYaceM2jH9JXksIqtnIBRy+vxQaPZglOUvm1VLppyF9+lULKV/3xODmNAoN9cNDzYqs6ZcWSu6Pasl6tN15Y/vNSQvt4RHGqRwkkEqkMID6QmhZ7zoH/8/i02bv7A6W+dVDLNNrk2+/G0yklOLSdDoQ8kc6ToZdrWAaa8iZcQtsJbpSsauq4wL0+GnV7a0dUXZ88HWx/vMuDL5SbLdPTeNgvybSQSpXSZKm+rELoY2L5pb+xX5/wsxlaB88CUoCTzjnl4FIt53JIHjQU+Ey0zW2R1mhN/n3BEeos0xxY1A+msxgfR+VtBDBSbjErDXYSKYIKb/zaGCstPh1EkVJGbb0mHvCkIm3oyn0vPM1p+1vy61NtLfBo7vtHACgfsMBJKzxvaawyyknH6wTzbtjOgkTBRLqbVRahNl6XkzyuQ0CwpBwqdU4pNJmwILSuckL+/SP49uCvblM6ml39M0NeNLxh6aVnGFMtNSWF8cT3yMB9KXdGO8O90Hn6OhTSJaZW2NW4TlVjNX7exQbsMmRVTfy8EVJEzZvHfKDz+FJd/4p67JJaGVpZC4Z1+8F05MgNZ+grBRRWb0CGPB2LXOQw8/Kl3P0tlXzGMGF2XIwRedl6imaBkx4p9oqMRJCud/bveJPkCeEb/L4OkeaEDOxZtUK/2YOVEP4sL+bhR/PfL5zdaDDLzx1cqQZYSESzJawZbKWCb4xoQ4ztEATFSMPRWBh7feZIa5lBaoQaU2q9DFZZFCiJvHGzmJ8FeETmkKn+fuB2pkc9PcU6TH86M+q0atLR/0xmZwp0Wff7tingxMKESP1cjFp9titJ+MTMfDTD880J8y6VB7XVtHMr0blcsOLrQGI/hpqx7HyNb6lzt2o7Km/2LvSJpS+2twKZDjO8WVB1/sudhRBC94XbCxVnSffpSqBONrzulOkFkOCL8Ms9PbWfs01ePT9WXlPlWLp1EA9sYnAcCHhxxY/G8qrH8vfNsyg73hpVUrVn/HaiI8wk70lcnfh9yVZV1qmRqNMBfaKPjU+QfPhgVCMVQRkKgMjxTsMBD3rqOIza77bnM6+zVuHSysWrmBwGepjXxNTihqRABsTAYfFsL7jkeITY4Gc94MHLNwOfF5l53VK1O/OhoD2OvKe1Sp6clvpQukN5t0B45JPszfGT/kEyK6ZlNcQH0ECq3uLNrhr9+gMrhcWbXZrtI6+O6Q4XFD29JTn8HVNmvrBu2aiCxIzEkL/LMDR67NoJsCZFVha//YcovYUE+XVktPblzr9RU4PzmatmqcC4QcRYNbORHN1rM++W5hkUnaz03Mr1oiWhIxNr1RCGtTcel7EKlpUdGGqGCOBl8QckSS7Jw2Oj5UxsHwai2pZXnCwmhTzl6LyAJzhjFiFedhQydjY2ihBieG2al0j4NPDiyow+Rs2vBoghC9E2lVuAJ4SEfc9mR0F5ly6hFD415rpeS0R63dxLqpD3+hjMfeHOGNWKrNKR/o9el4pfcpp9uBD0IRNvAz7HHeU6RfD0defEEFW+ticEonPTzUp5YzYHQdW3Lc+BbhvpZ1AKwHh3Bj6Zw4OyLaxKGWhIWCfgd0w/a/0q9JNUL X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: edf7fabb-6481-402f-44d4-08dbae588dcf X-MS-Exchange-CrossTenant-AuthSource: AM6PR04MB4838.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Sep 2023 21:39:16.4047 (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: FI8e4dadcGdDMJBy12u4+R7UoOXZyKnHykbwP2j1GfqgYOzerfyGEfGliDK99FyghEeugA94IytNP8Bnc5S7JA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB9256 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230905_143926_191614_982955EF X-CRM114-Status: GOOD ( 19.29 ) 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 Add tty over I3C slave function driver. Signed-off-by: Frank Li --- drivers/i3c/Kconfig | 1 + drivers/i3c/Makefile | 1 + drivers/i3c/func/Kconfig | 9 + drivers/i3c/func/Makefile | 3 + drivers/i3c/func/tty.c | 345 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 359 insertions(+) create mode 100644 drivers/i3c/func/Kconfig create mode 100644 drivers/i3c/func/Makefile create mode 100644 drivers/i3c/func/tty.c diff --git a/drivers/i3c/Kconfig b/drivers/i3c/Kconfig index bdc173bc0da12..fa0f63e0e3e6e 100644 --- a/drivers/i3c/Kconfig +++ b/drivers/i3c/Kconfig @@ -50,4 +50,5 @@ config I3C_SLAVE_CONFIGFS if I3C_SLAVE source "drivers/i3c/slave/Kconfig" +source "drivers/i3c/func/Kconfig" endif #I#C_SLAVE diff --git a/drivers/i3c/Makefile b/drivers/i3c/Makefile index ef1acbe13fe60..7814bf2dd9b40 100644 --- a/drivers/i3c/Makefile +++ b/drivers/i3c/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_I3C) += master/ obj-$(CONFIG_I3C_SLAVE) += slave.o obj-$(CONFIG_I3C_SLAVE_CONFIGFS) += i3c-cfs.o obj-$(CONFIG_I3C_SLAVE) += slave/ +obj-$(CONFIG_I3C_SLAVE) += func/ diff --git a/drivers/i3c/func/Kconfig b/drivers/i3c/func/Kconfig new file mode 100644 index 0000000000000..f122e2cc32de8 --- /dev/null +++ b/drivers/i3c/func/Kconfig @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 + +config I3C_SLAVE_FUNC_TTY + tristate "PCI Endpoint Test driver" + depends on I3C_SLAVE + help + I3C Slave TTY Function Driver + + General TTY over I3C slave controller function drivers. diff --git a/drivers/i3c/func/Makefile b/drivers/i3c/func/Makefile new file mode 100644 index 0000000000000..db3262e402edd --- /dev/null +++ b/drivers/i3c/func/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_I3C_SLAVE_FUNC_TTY) += tty.o diff --git a/drivers/i3c/func/tty.c b/drivers/i3c/func/tty.c new file mode 100644 index 0000000000000..be43878913452 --- /dev/null +++ b/drivers/i3c/func/tty.c @@ -0,0 +1,345 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2023 NXP + * Author: Frank Li + */ + +#include +#include +#include +#include + +#define PORT_I3C 124 + +struct ttyi3c_port { + struct uart_port port; + struct i3c_slave_func *i3cdev; + unsigned long buffer; + struct work_struct work; + struct workqueue_struct *workqueue; +}; + +static struct uart_driver ttyi3c_reg = { + .owner = THIS_MODULE, + .driver_name = "ttySI3C", + .dev_name = "ttySI3C", + .nr = 1, +}; + +static unsigned int ttyi3c_tx_empty(struct uart_port *port) +{ + return 0; +} + +static void ttyi3c_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + +} + +static unsigned int ttyi3c_get_mctrl(struct uart_port *port) +{ + return 0; +} + +static void ttyi3c_stop_tx(struct uart_port *port) +{ +} + +static void ttyi3c_stop_rx(struct uart_port *port) +{ +} + +static void ttyi3c_break_ctl(struct uart_port *port, int break_state) +{ +} + +static int ttyi3c_startup(struct uart_port *port) +{ + return 0; +} + +static void ttyi3c_shutdown(struct uart_port *port) +{ + +} + +static void ttyi3c_uart_pm(struct uart_port *port, unsigned int state, unsigned int oldstate) +{ + +} + +static void +ttyi3c_set_termios(struct uart_port *port, struct ktermios *termios, const struct ktermios *old) +{ + +} + +static const char *ttyi3c_type(struct uart_port *port) +{ + return "I3CTTY"; +} + +static void ttyi3c_release_port(struct uart_port *port) +{ + +} + +static int ttyi3c_request_port(struct uart_port *port) +{ + return 0; +} + +static void ttyi3c_config_port(struct uart_port *port, int flags) +{ + +} + +static int ttyi3c_verify_port(struct uart_port *port, struct serial_struct *ser) +{ + return 0; +} + +static void ttyi3c_flush_buffer(struct uart_port *port) +{ + +} + +static void ttyi3c_start_tx(struct uart_port *port) +{ + struct ttyi3c_port *sport = container_of(port, struct ttyi3c_port, port); + + queue_work(sport->workqueue, &sport->work); +} + +static void i3c_slave_tty_rx_complete(struct i3c_request *req) +{ + struct ttyi3c_port *port = req->context; + + if (req->status == I3C_REQUEST_CANCEL) { + i3c_slave_ctrl_free_request(req); + return; + } + + for (int i = 0; i < req->actual; i++) { + if (tty_insert_flip_char(&port->port.state->port, *(u8 *)(req->buf + i), 0) == 0) + port->port.icount.buf_overrun++; + } + + tty_flip_buffer_push(&port->port.state->port); + req->actual = 0; + req->status = 0; + i3c_slave_ctrl_queue(req, GFP_KERNEL); +} + + +static void i3c_slave_tty_tx_complete(struct i3c_request *req) +{ + struct ttyi3c_port *port = req->context; + struct circ_buf *xmit = &port->port.state->xmit; + + if (req->status == I3C_REQUEST_CANCEL) { + i3c_slave_ctrl_free_request(req); + return; + } + + uart_xmit_advance(&port->port, req->actual); + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(&port->port); + + + i3c_slave_ctrl_free_request(req); +} + +static void i3c_slave_tty_i3c_work(struct work_struct *work) +{ + struct ttyi3c_port *sport = container_of(work, struct ttyi3c_port, work); + struct circ_buf *xmit = &sport->port.state->xmit; + int cnt = CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE); + int actual; + int ret; + + if (cnt == 0) + return; + + if (cnt > 0) { + struct i3c_request *req = i3c_slave_ctrl_alloc_request(sport->i3cdev->ctrl, + GFP_KERNEL); + if (!req) + return; + + req->length = ((xmit->tail + cnt) > UART_XMIT_SIZE) ? UART_XMIT_SIZE - xmit->tail : + cnt; + req->buf = xmit->buf + xmit->tail; + req->complete = i3c_slave_tty_tx_complete; + req->context = sport; + req->tx = true; + + if (i3c_slave_ctrl_queue(req, GFP_KERNEL)) + return; + + if ((xmit->tail + cnt) > UART_XMIT_SIZE) { + req = i3c_slave_ctrl_alloc_request(sport->i3cdev->ctrl, GFP_KERNEL); + if (!req) + return; + req->buf = xmit->buf; + req->length = xmit->tail + cnt - UART_XMIT_SIZE; + req->complete = i3c_slave_tty_tx_complete; + + if (i3c_slave_ctrl_queue(req, GFP_KERNEL)) + return; + } + } + + i3c_slave_ctrl_raise_ibi(sport->i3cdev->ctrl, NULL, 0); +} + +static const struct uart_ops ttyi3c_pops = { + .tx_empty = ttyi3c_tx_empty, + .set_mctrl = ttyi3c_set_mctrl, + .get_mctrl = ttyi3c_get_mctrl, + .stop_tx = ttyi3c_stop_tx, + .start_tx = ttyi3c_start_tx, + .stop_rx = ttyi3c_stop_rx, + .break_ctl = ttyi3c_break_ctl, + .startup = ttyi3c_startup, + .shutdown = ttyi3c_shutdown, + .pm = ttyi3c_uart_pm, + .set_termios = ttyi3c_set_termios, + .type = ttyi3c_type, + .request_port = ttyi3c_request_port, + .release_port = ttyi3c_release_port, + .config_port = ttyi3c_config_port, + .verify_port = ttyi3c_verify_port, + .flush_buffer = ttyi3c_flush_buffer, +#if defined(CONFIG_CONSOLE_POLL) + .poll_init = ttyi3c_poll_init, + .poll_get_char = ttyi3c_poll_get_char, + .poll_put_char = ttyi3c_poll_put_char, +#endif +}; + +static int i3c_slave_tty_bind(struct i3c_slave_func *func) +{ + const struct i3c_slave_ctrl_features *feature; + unsigned int rxfifo_size; + struct ttyi3c_port *port; + struct i3c_request *req; + int offset = 0; + int ret; + + feature = i3c_slave_ctrl_get_features(func->ctrl); + if (!feature) + return -EINVAL; + + rxfifo_size = feature->rx_fifo_sz; + + if (!rxfifo_size) + rxfifo_size = 16; + + port = dev_get_drvdata(&func->dev); + + port->buffer = get_zeroed_page(GFP_KERNEL); + if (!port->buffer) + return -ENOMEM; + + if (i3c_slave_ctrl_set_config(func->ctrl, func)) { + dev_err(&func->dev, "failure set i3c config\n"); + return -EINVAL; + } + + req = i3c_slave_ctrl_alloc_request(func->ctrl, GFP_KERNEL); + do { + req->buf = (void *) (port->buffer + offset); + req->length = rxfifo_size; + req->context = port; + req->complete = i3c_slave_tty_rx_complete; + offset += rxfifo_size; + + if (i3c_slave_ctrl_queue(req, GFP_KERNEL)) + break; + } while (req == NULL || offset >= PAGE_SIZE); + + if (i3c_slave_ctrl_set_config(func->ctrl, func)) { + dev_err(&func->dev, "failure set i3c config\n"); + return -EINVAL; + } + + ret = uart_register_driver(&ttyi3c_reg); + if (ret) + return ret; + + ret = uart_add_one_port(&ttyi3c_reg, &port->port); + if (ret) + goto err_one_port; + + ret = i3c_slave_ctrl_enable(func->ctrl); + if (ret) + goto err_ctrl_enable; + + return 0; + +err_ctrl_enable: + uart_remove_one_port(&ttyi3c_reg, &port->port); +err_one_port: + uart_unregister_driver(&ttyi3c_reg); + dev_err(&func->dev, "bind failure\n"); + + return ret; +} + +static void i3c_slave_tty_unbind(struct i3c_slave_func *func) +{ + struct ttyi3c_port *port; + + port = dev_get_drvdata(&func->dev); + + i3c_slave_ctrl_disable(func->ctrl); + i3c_slave_ctrl_cancel_all_reqs(func->ctrl, 0); + i3c_slave_ctrl_cancel_all_reqs(func->ctrl, 1); + uart_remove_one_port(&ttyi3c_reg, &port->port); + uart_unregister_driver(&ttyi3c_reg); + + free_page(port->buffer); +} + +static struct i3c_slave_func_ops i3c_tty_ops = { + .bind = i3c_slave_tty_bind, + .unbind = i3c_slave_tty_unbind, +}; + +static int i3c_tty_probe(struct i3c_slave_func *func) +{ + struct device *dev = &func->dev; + struct ttyi3c_port *port; + + port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); + if (!port) + return -ENOMEM; + + port->i3cdev = func; + port->port.dev = &func->dev; + port->port.ops = &ttyi3c_pops; + port->port.type = PORT_I3C; + + dev_set_drvdata(&func->dev, port); + + port->workqueue = alloc_workqueue("%s", 0, 0, dev_name(&func->dev)); + if (!port->workqueue) + return -ENOMEM; + + INIT_WORK(&port->work, i3c_slave_tty_i3c_work); + + return 0; +} + +static void i3c_tty_remove(struct i3c_slave_func *func) +{ + struct ttyi3c_port *port; + + port = dev_get_drvdata(&func->dev); + + destroy_workqueue(port->workqueue); +} + +DECLARE_I3C_SLAVE_INIT(tty, i3c_tty_probe, i3c_tty_remove, &i3c_tty_ops); From patchwork Tue Sep 5 21:38:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Li X-Patchwork-Id: 13375090 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 DC078CA1008 for ; Tue, 5 Sep 2023 21:39:31 +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:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=b4sHzSMy9QMqjmKt2yshQ036KeYlHDDMesKQDcDCaqY=; b=qBH243LBUXhPEt /o2PsxiO9PqtRiAYH86sti386UFMaM+/M7SP8yI3LbH3YLeGRsmuBnhRT/B1ngaZIajSs3VmTeRVE YClR6ZgB0OOKjSYMM+81X4NhqlfTzdd2TIHNA3sk8IBtqtlrdy1ecH52QS7NAhoFEODx4888H6vVx +V71fsQE41NupsJl1eHWV2DpzErdF2M8UCajTrozfec3FBTKyQfeTBVae+uJlCRBjnaaPy3nANNoc mVm1Sv5BrMropv0cQblXc7G+RzBieVJ20+56zBvNukFrf1+lsIUqvjla9MJm7zBr+tsrNBTwcNtnA b2MvjdvwcwYp5StfKnyw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qddlj-006lqH-1v; Tue, 05 Sep 2023 21:39:31 +0000 Received: from mail-db3eur04on061b.outbound.protection.outlook.com ([2a01:111:f400:fe0c::61b] helo=EUR04-DB3-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qddlg-006lfI-0u for linux-i3c@lists.infradead.org; Tue, 05 Sep 2023 21:39:30 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=NIveLh10H5aopjMzZD3a42DuRq+IvxB6dcigjBGTChsZt4IjVtH4JCtnOv1m4vEsbU61YN3nDMCTZLHK0R9YdL6di9L+1alSr3GeVAADuY2o9/kbbFJWTynh/PSmPoKNdTvMj/ZXdulXOubiCDRZpvJTI1shWdjtVCnuyjq+JGln9bqEaigzFqn1o9mp81Yh0Y9HaD7mTt5OuZUK1gLj4WB11aQeC1FTAjBZd6ynQMpRVjFEwsFDzzA9i7ECmgr6qcUuWjxBPos8Vic5Ko+1N8l0ukA+Y7MWMb5DUMdJiPdFQ62MbO50E9t0R6vfdUVdd8tO+5Bxj4tPa41ijLyhww== 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=XlawwosMXrMoZ+wp3paBmDaG6KOjXo8Zh5YFVNjP46s=; b=erxXcWPwehL3scO/4jCgBc4EoImHK7T2BF0UztbrqmymJM76B7tb6MY7QDtZVGSbMf3IfVOPzJEVdPhMJXD4F5PdXImXXO0szavLLYRLs/Pbj0ag2kJ4HIl2ErtzA5rypO3L0XnfM7e7TA01IyU2+2R1vAO0KTbtmwa3+c8fF8WwxL49wdAmW6AWiRNWzZI0gfwc+kW8vr7CxHdjEX79D/ZekRYwxpXKHSoQX52lbYcyeza2CIB+fZf0A3ayzbRI+7W651OmNXk8+3oY0ElHmDUvkwG8Ihnr8IQeNsJKGwCUNmw2Y0Io/Z5doesosORLRk1TNVrz/uVk4Vl9AsALIw== 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=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=XlawwosMXrMoZ+wp3paBmDaG6KOjXo8Zh5YFVNjP46s=; b=LsyOlxEweBR3/hZoZ0OJnVMvjC+xReKiPVLm0QSm2fOfEjlKwyLl1tfSSZ7IY/BVL/RFa9PcZ69aFwgs9nUKui7EhwsBykYORpT5SLAzk0lA/a5GxqCFkLWWKGPYB6wfeJi5preggybBvAWB6MWU8f/xnhmL0nXkDxmJhCS6hRw= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from AM6PR04MB4838.eurprd04.prod.outlook.com (2603:10a6:20b:4::16) by PAXPR04MB9256.eurprd04.prod.outlook.com (2603:10a6:102:2ba::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6745.34; Tue, 5 Sep 2023 21:39:18 +0000 Received: from AM6PR04MB4838.eurprd04.prod.outlook.com ([fe80::aa90:117d:c1d0:346a]) by AM6PR04MB4838.eurprd04.prod.outlook.com ([fe80::aa90:117d:c1d0:346a%3]) with mapi id 15.20.6745.030; Tue, 5 Sep 2023 21:39:18 +0000 From: Frank Li To: miquel.raynal@bootlin.com Cc: Frank.Li@nxp.com, alexandre.belloni@bootlin.com, conor.culhane@silvaco.com, imx@lists.linux.dev, linux-i3c@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 8/9] tty: serial: add tty over I3C master side driver Date: Tue, 5 Sep 2023 17:38:41 -0400 Message-Id: <20230905213842.3035779-9-Frank.Li@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230905213842.3035779-1-Frank.Li@nxp.com> References: <20230905213842.3035779-1-Frank.Li@nxp.com> X-ClientProxiedBy: SJ0PR03CA0215.namprd03.prod.outlook.com (2603:10b6:a03:39f::10) To AM6PR04MB4838.eurprd04.prod.outlook.com (2603:10a6:20b:4::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AM6PR04MB4838:EE_|PAXPR04MB9256:EE_ X-MS-Office365-Filtering-Correlation-Id: 020a5abf-5767-44ef-7ecf-08dbae588f13 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 5Xf2k0Xpvbu/NTAKjP5FXz2SqtlmSGWTQ0sChxnGeQXqr+Ek8o+4cUgsimm/VQr8Epc0GgjmyKEW7bG8Geb7Jml0CZkWS/ZXSGDJXG0ecEG5DiRCYfhonkJFbhu8tyHkw4jeulLSxLIiTk5iNiESk5iHHKsrtqSZaPebFt2Jf5ufklMMOJwgMe1t6yWU2fE1ceC2RfwNJCIw2Gh+xTf5eDYYloq+VnJnDeorMqol+DFQl+oS4yfw1TDj3AliYKKMlUkLwt7ipu84PqDakPx/AnmLqBi39GZS0XbxSOU7H+iW7j59hZXGmVmVRUNKI9127GB0bCKjvkWmie/ceeL0zuaMJUv2CZbInrgea+A6tS+0O93ux9+htZzaVqAHs6U9ILpO+eBMSYYPWZl6RnFszIOZ8Sxh/eifq50kWadkZeM8Oqmiqenj+rzwgXNIz63hmnc6s9C+nL7/B7OJsWP0WHrJpiIapLcQIPVhGdFc+g/kVW3BchaJ0GDE/E7tsculxgo0gkV/ovumB8uWFF/uLS/CjF8sOC2bTRZV5MGlUGGa5kRIWuFoVAA5X2V3CYnlgJ/l1w1tiNg0DwuKisv1iDRtUWOL6wz9uq3SiCfZFpY7k3aGW0NSKIviBtnjoqL5 X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:AM6PR04MB4838.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(396003)(376002)(39860400002)(366004)(346002)(136003)(186009)(1800799009)(451199024)(2906002)(83380400001)(6486002)(52116002)(6506007)(6916009)(316002)(66946007)(66556008)(66476007)(478600001)(26005)(6666004)(5660300002)(1076003)(41300700001)(8676002)(8936002)(6512007)(2616005)(4326008)(36756003)(38100700002)(38350700002)(86362001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: jrcqDp+nKzK6Hmqb1bn7lPKo+FbONQPk2/CtHz0oTQ2uHt7csCpWiNJ2PJ4eZ1cagxOmvFXck/nMw9vpUJmOfml6wlokRHgxw9xZ+AN9jelUvAZkCP0tMICA2bXpy1uT+SeXk9hy1MkzCoUA3c1ubbyDUh1iBF/0dcJO/nt0F6RvbaJfbWnLmNae9SGdjhpioi408MRPX06jCaEu6McN6u1lzbLf0u8JNZAOfq7P3OdqJzewqdkusagljQYJkTsb5bGa/46RBjYdzsmJwOQ3RUfZ+wSM8wB7cycoZVhSo3FrqaM1axErk4BXPQOQ0Cyk5lHHrn4dHEhPJYYGzzQ37gk+xbSGFY2JujGyrB7j9dV0GqDKwMGXqHDBf5keRwOc6ZcnCfwPSSeAS6ImOFFYHaBdqvXr68cfhndNrJazAyc7/F+n8kmg4XxZ7KNxQloTmPgRMNQIzlDYpJuAq4GMzgGYKBCaOkdTcq+tVr2eYmm+awCdzxLp+a3rkIXE7gjXs52rUForuuMAXrVvI2X1lLTbMuWs6z08YnWe5YjFvTi04FH8GgJzX7bFo5+/lodQzOO7rqDBqNQOpc4VacZQJc/Y8z6x3D973zEXgTcAikxve4A9QeVEg89TAI+x59Cmyfk+cW3c50JFaPKm969KlvJp/fyEhkNyux3EA+1tQ0VlItCLJVEm9Bc83Uv/paYiSz69ipM1xIm+GHcXz+YNcvoI89H5VGtGX7L9X9YAPmupvvYBo4uVdRlmFibYwvSBH6PnwFrfXet2leN3FsZh148yg9/pb7BhFMGXtCS1/OyTQerwsMTB78qsoZ41J7C1k4A8Oz+3a5Se8CB5mdEFjTuRHB9riWzM53WBgCGO6P9wLEH+Lbx+j1cwPtfJx3THEGuQbqagJGW52GqDglFdjTe4i0oe+09X0a8PDz5qxSPHEBUy9/hakdVDma1OaB7rSk9ZMWIzHTRH4IEuPElu2MnFMY97lBWWSdQXBTNw/y7cPkKJsFZ/Hxxu0WUd0YTktXmQ5rgurtIFry1OiKFk+62YI/GBkfWG6czNNxV2ctdiEvkC6IfdXtx3TN3aizUnD0Xw/Ahytgw9qTEFFxkjPV+N5cVUqz1nzwuI4wfSF561KLIdzzRUJgZmFRfvYzA189TcvFbNziSodHt7U8xw8PbFfMQgqqWEBjuBM6e7nsb2KnLdyvyTlXWAjLwXnZdKnq/Srxbz0aVXrtMpAmQFnOCrv6GmTzISTFw5qIMGlV+pqX8T/KmLFjKoc0wMRkAhXEqHZ9dyptNln6PAo+GkZk0pegSX6cLuW3i340KXczDqHNGrjumkrlz6nSQHMPp0wORaoosgN3wfgoTFulaHs7Y69olZ4v2WFVlWwHiJQsX98HoM9NXXMhGdB3hyS2hbqY+3w1W9KO4XrPXzkR/8ZvGAfzV5NcRHoddBtJfqDRRPMaE8+qV5lecRi97BpW1FZbO08q9+G+QSUqi71VRMk9b/zdCZjWs3peMbn4hfjp9P64rERp+gaJdMghk6G4/TGJtqZDQHhzUtHEVVIqFplrlbFIRkn4JWD+Z90pqp/4oaFRbAuPFK3BjF0ZKgorlN X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 020a5abf-5767-44ef-7ecf-08dbae588f13 X-MS-Exchange-CrossTenant-AuthSource: AM6PR04MB4838.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Sep 2023 21:39:18.5569 (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: j+tOKtF5PYf5t353wafuWwuyo4FQVHRHPZ6KWbb+KPNN8NhI+2RdzUj10qR3N53NUGSszJKpY43NwFYm7FFxtg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB9256 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230905_143928_322578_704F6672 X-CRM114-Status: GOOD ( 21.12 ) 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 This is master side tty driver for tty over i3c. Signed-off-by: Frank Li --- drivers/tty/serial/Kconfig | 6 + drivers/tty/serial/Makefile | 1 + drivers/tty/serial/ttyi3c.c | 276 ++++++++++++++++++++++++++++++++++++ 3 files changed, 283 insertions(+) create mode 100644 drivers/tty/serial/ttyi3c.c diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index bdc568a4ab669..2ceafe94cd1dc 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1578,6 +1578,12 @@ config SERIAL_NUVOTON_MA35D1_CONSOLE but you can alter that using a kernel command line option such as "console=ttyNVTx". +config SERIAL_I3C + tristate "tty over i3c" + depends on I3C + help + Select this options if you'd like use UART over I3C master controller + endmenu config SERIAL_MCTRL_GPIO diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 138abbc897381..60c101809cdcf 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -88,6 +88,7 @@ obj-$(CONFIG_SERIAL_MILBEAUT_USIO) += milbeaut_usio.o obj-$(CONFIG_SERIAL_SIFIVE) += sifive.o obj-$(CONFIG_SERIAL_LITEUART) += liteuart.o obj-$(CONFIG_SERIAL_SUNPLUS) += sunplus-uart.o +obj-$(CONFIG_SERIAL_I3C) += ttyi3c.o # GPIOLIB helpers for modem control lines obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o diff --git a/drivers/tty/serial/ttyi3c.c b/drivers/tty/serial/ttyi3c.c new file mode 100644 index 0000000000000..e2912c8bac87d --- /dev/null +++ b/drivers/tty/serial/ttyi3c.c @@ -0,0 +1,276 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2023 NXP. + * + * Author: Frank Li + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEVICE_NAME "ttyI3C" +#define PORT_I3C 124 + +struct ttyi3c_port { + struct uart_port port; + unsigned int txfifo_size; + unsigned int rxfifo_size; + void *buffer; + struct i3c_device *i3cdev; + struct work_struct work; + struct workqueue_struct *workqueue; +}; + +static struct uart_driver ttyi3c_reg = { + .owner = THIS_MODULE, + .driver_name = "fsl_ttyi3c", + .dev_name = DEVICE_NAME, + .nr = 1, +}; + +static const struct i3c_device_id fsl_tty_i3c_ids[] = { + I3C_DEVICE(0x011B, 0x1000, NULL), + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(i3c, fsl_tty_i3c_ids); + +static unsigned int ttyi3c_tx_empty(struct uart_port *port) +{ + return 0; +} + +static void ttyi3c_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + +} + +static unsigned int ttyi3c_get_mctrl(struct uart_port *port) +{ + return 0; +} + +static void ttyi3c_stop_tx(struct uart_port *port) +{ +} + +static void ttyi3c_stop_rx(struct uart_port *port) +{ + +} + +static void ttyi3c_break_ctl(struct uart_port *port, int break_state) +{ + +} + +static int ttyi3c_startup(struct uart_port *port) +{ + return 0; +} + +static void ttyi3c_shutdown(struct uart_port *port) +{ + +} + +static void ttyi3c_uart_pm(struct uart_port *port, unsigned int state, unsigned int oldstate) +{ + +} + +static void +ttyi3c_set_termios(struct uart_port *port, struct ktermios *termios, const struct ktermios *old) +{ + +} + +static const char *ttyi3c_type(struct uart_port *port) +{ + return "I3CTTY"; +} + +static void ttyi3c_release_port(struct uart_port *port) +{ + +} + +static int ttyi3c_request_port(struct uart_port *port) +{ + return 0; +} + +static void ttyi3c_config_port(struct uart_port *port, int flags) +{ + +} + +static int ttyi3c_verify_port(struct uart_port *port, struct serial_struct *ser) +{ + return 0; +} + +static void ttyi3c_flush_buffer(struct uart_port *port) +{ + +} + +static void ttyi3c_start_tx(struct uart_port *port) +{ + struct ttyi3c_port *sport = container_of(port, struct ttyi3c_port, port); + + queue_work(sport->workqueue, &sport->work); +} + +static const struct uart_ops ttyi3c_pops = { + .tx_empty = ttyi3c_tx_empty, + .set_mctrl = ttyi3c_set_mctrl, + .get_mctrl = ttyi3c_get_mctrl, + .stop_tx = ttyi3c_stop_tx, + .start_tx = ttyi3c_start_tx, + .stop_rx = ttyi3c_stop_rx, + .break_ctl = ttyi3c_break_ctl, + .startup = ttyi3c_startup, + .shutdown = ttyi3c_shutdown, + .pm = ttyi3c_uart_pm, + .set_termios = ttyi3c_set_termios, + .type = ttyi3c_type, + .request_port = ttyi3c_request_port, + .release_port = ttyi3c_release_port, + .config_port = ttyi3c_config_port, + .verify_port = ttyi3c_verify_port, + .flush_buffer = ttyi3c_flush_buffer, +}; + +static void +i3c_controller_irq_handler(struct i3c_device *dev, const struct i3c_ibi_payload *payload) +{ + + struct ttyi3c_port *sport = dev_get_drvdata(&dev->dev); + struct i3c_priv_xfer xfers; + int i = 0; + + memset(&xfers, 0, sizeof(xfers)); + + xfers.data.in = sport->buffer; + xfers.len = 16; + xfers.rnw = 1; + + i3c_device_do_priv_xfers(sport->i3cdev, &xfers, 1); + + for (i = 0; i < xfers.actual; i++) + if (tty_insert_flip_char(&sport->port.state->port, *(u8 *)(sport->buffer + i), 0) + == 0) + sport->port.icount.buf_overrun++; + + tty_flip_buffer_push(&sport->port.state->port); +} + +static void fsl_tty_i3c_work(struct work_struct *work) +{ + struct ttyi3c_port *sport = container_of(work, struct ttyi3c_port, work); + struct circ_buf *xmit = &sport->port.state->xmit; + int cnt = CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE); + struct i3c_priv_xfer xfers; + int actual; + int ret; + + if (cnt == 0) + return; + + if (cnt > 0) { + xfers.rnw = 0; + xfers.len = ((xmit->tail + cnt) > UART_XMIT_SIZE) ? UART_XMIT_SIZE - xmit->tail : + cnt; + xfers.data.out = xmit->buf + xmit->tail; + + ret = i3c_device_do_priv_xfers(sport->i3cdev, &xfers, 1); + + actual = ret ? xfers.actual : xfers.len; + + uart_xmit_advance(&sport->port, actual); + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(&sport->port); + + cnt -= actual; + } + + if (cnt) + queue_work(sport->workqueue, &sport->work); +} + +static int fsl_tty_i3c_probe(struct i3c_device *i3cdev) +{ + struct ttyi3c_port *port; + struct i3c_ibi_setup req; + int ret; + + port = devm_kzalloc(&i3cdev->dev, sizeof(*port), GFP_KERNEL); + if (!port) + return -ENOMEM; + + port->i3cdev = i3cdev; + port->port.ops = &ttyi3c_pops; + port->port.type = PORT_I3C; + port->port.dev = &i3cdev->dev; + port->buffer = devm_kzalloc(&i3cdev->dev, UART_XMIT_SIZE, GFP_KERNEL); + + req.max_payload_len = 8; + req.num_slots = 4; + req.handler = &i3c_controller_irq_handler; + + dev_set_drvdata(&i3cdev->dev, port); + + INIT_WORK(&port->work, fsl_tty_i3c_work); + port->workqueue = alloc_workqueue("%s", 0, 0, dev_name(&i3cdev->dev)); + if (!port->workqueue) + return -ENOMEM; + + ret = uart_register_driver(&ttyi3c_reg); + if (ret) + return ret; + + ret = uart_add_one_port(&ttyi3c_reg, &port->port); + if (ret) + goto err_add_one_port; + + ret = i3c_device_request_ibi(i3cdev, &req); + if (ret) + goto err_request_ibi; + + ret = i3c_device_enable_ibi(i3cdev); + if (ret) + goto err_enable_ibi; + + return 0; + +err_enable_ibi: + i3c_device_free_ibi(i3cdev); +err_request_ibi: + uart_remove_one_port(&ttyi3c_reg, &port->port); +err_add_one_port: + uart_unregister_driver(&ttyi3c_reg); + + return ret; +} + +static struct i3c_driver fsl_tty_i3c_driver = { + .driver = { + .name = "ttyi3c", + }, + .probe = fsl_tty_i3c_probe, + .id_table = fsl_tty_i3c_ids, +}; + +module_i3c_driver(fsl_tty_i3c_driver); +MODULE_LICENSE("GPL"); From patchwork Tue Sep 5 21:38:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Li X-Patchwork-Id: 13375091 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 5519DCA1010 for ; Tue, 5 Sep 2023 21:39:32 +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:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=UmYiadsComSc1RGCKfjDmmwdwAEJh6ZYI6gIrFgvp1o=; b=kh1otRihgRXGK9 CxiTiBW8hblajaeegym2pKIA3WGSYlbdEsR5g0Fdi9m5HHKm4Y+t4e/70elt2wk/ELliZnLv8VyOJ KqEZgzLajqmGVBUP6mb4jrPQzrso7wiTkb+//yMOmJGP8We2//ysbc2Xr25RlN8qfXNVNhTsT5i74 tCmbkmWCW2asxujRs8Ic0vzmENrrAfExAynus41unWFFmbjfBkRsl1pgrDX9Es8irGUiZ4kcHyBI8 5AAVrKAd/Hqo4qxSiVyz0ITdx5Ae55FhAtRJH3pq5iu/Mp6tyUh+ifmqM69YGLjVMRiImbMSlfhyu zSCoyT+fiEB5QwSrSwtw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qddlj-006lqY-2y; Tue, 05 Sep 2023 21:39:31 +0000 Received: from mail-vi1eur02on20617.outbound.protection.outlook.com ([2a01:111:f400:fe16::617] helo=EUR02-VI1-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qddlf-006lnE-1z for linux-i3c@lists.infradead.org; Tue, 05 Sep 2023 21:39:30 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=h+KBS3R8nzxicoiFiQSG3I3jQpk8xcqwTUzeN32AH5FSZrTQfOmQhElRvyq/67KW/0QioK+X8YLWacN/7JiHzyqFmYJKyaGTzH/tY3YiOitPQsOFl++Hv3aefPIkrCLQJYI+tQc44PNMwJBhOu6wC2v7x8ARX96di7XlceyWc+EnnB8kxg+ERYqo0UL2tckF8xVMgABoyLMPIndOpFQWTlO430UhvI5gH6ahMQ18OfJIa+eYKyXciItKj4taYzA+H2Dk4aBwgDRKnNV2PPT95wWFiiWanam0BSk9KCoYoF5WZytr7USZHcvkHk9NslOv517azZi+2BaB0SPkoKMmbQ== 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=vDAV/oMkZ1fz60cAdAxt4H3rVGFC+p9cVJ/KX9+e6iQ=; b=FqYMSecmApwYM7JcbH/zC/UvALvfkRafUJzusNdCztMlDKAZEsiIxCtf28GU7d4iusXVe1oOQ3BVypv8P3Wjaw2EczDKwNZgDP5x+tQn+Xsv1eVjhtn6cw+ACZcXqIDszf70UyNdg1KKYLf2wHl3oj+QQNEO5bOJAwm+st64d4TbiKS2O4VAUBLriWpZoViyeYXDfeJX+WX1IMqiOSg5ob8Wyl9+UngaOnYRGVgBsqJS+YO6CgTJc9tiAiHBr3kJcsGNcBseEvATyS2+2xip20dcZ5w5AEvvQCOYFeXNrNVAlIwuX2Z3E9SPAVGo17hI1nft1P6rocbR5NjLrCAHsw== 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=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=vDAV/oMkZ1fz60cAdAxt4H3rVGFC+p9cVJ/KX9+e6iQ=; b=iEVGaWFYBJSnG+SCoVQcOWVgKxk8hrHLV72iQhPW9ZZCHMvTuva3SQxtKuoiY7e3wF4eQybHQRHnI2mh+IzwNOzj5g83VfJfDWL8Vcu2uP3dhWqU0PEVUEmRCn5ClaxKex/XAL824hDrLSoo/whK5JFlENdTr0LTWg4tUC7Nm8E= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from AM6PR04MB4838.eurprd04.prod.outlook.com (2603:10a6:20b:4::16) by DB8PR04MB6859.eurprd04.prod.outlook.com (2603:10a6:10:119::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6745.27; Tue, 5 Sep 2023 21:39:21 +0000 Received: from AM6PR04MB4838.eurprd04.prod.outlook.com ([fe80::aa90:117d:c1d0:346a]) by AM6PR04MB4838.eurprd04.prod.outlook.com ([fe80::aa90:117d:c1d0:346a%3]) with mapi id 15.20.6745.030; Tue, 5 Sep 2023 21:39:20 +0000 From: Frank Li To: miquel.raynal@bootlin.com Cc: Frank.Li@nxp.com, alexandre.belloni@bootlin.com, conor.culhane@silvaco.com, imx@lists.linux.dev, linux-i3c@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 9/9] Documentation: i3c: Add I3C slave mode controller and function Date: Tue, 5 Sep 2023 17:38:42 -0400 Message-Id: <20230905213842.3035779-10-Frank.Li@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230905213842.3035779-1-Frank.Li@nxp.com> References: <20230905213842.3035779-1-Frank.Li@nxp.com> X-ClientProxiedBy: SJ0PR03CA0215.namprd03.prod.outlook.com (2603:10b6:a03:39f::10) To AM6PR04MB4838.eurprd04.prod.outlook.com (2603:10a6:20b:4::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AM6PR04MB4838:EE_|DB8PR04MB6859:EE_ X-MS-Office365-Filtering-Correlation-Id: fa96b242-ed03-45d4-dfc0-08dbae58905e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: mvn2+c7OFMyWngh+9vF+LTGVug9mbF4NkQ928dOCMt1L7MBcBiOPYel8HXaTV4ivTlY2QWcIaMUJCNDUgewJiY+WqJ0UCBbldM6Ulcuh824KTqKF+T9ebhGSByJIdZTsr81cy/t9qm/e1vGU37vC/0hbOQJZwldKuYUTAnOQzhZfg7of4AUT8dUG3u4Fc3b6eaN6z21WUFfUfSDYyn3OiuInsX9n60Ex3u6sNVBDUgfzilQ5K5tNLQy/IM+tW8LiIgq8y7mU3gvuFQprYZu79NHGAYOcFCSA19Z8kUfFdXPqWxDVyjb/hG8XKHIHI+ElCFG76gD2g3Zz5DKaik4pevTpYhLq/7fo4psaFsniH6rMjbcq7/Su8UBQfnslBqBU2unv53ePmM8GY2INo+UdgXusS8zml0Jdqab1w5QnSBuL0Hr+gCJ8HggD5amUrv6Am2s/Qda8xEoemEGZ1HuA3hef7fep5SJX7Sod1/9XQEUelvnn4y8EtsgPv5hFQdidedyTqhtNvHHSFntLZMGToSW4vzdFyfJjXVcTfGClaN0DVXfStL8LeiasQDZIUi+RS3YV6QqqMbA1C20EtDNQ1PfG1cxLO607ycDocjEhgMdCzYpqFQ77fXGuYNnPagSC X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:AM6PR04MB4838.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230031)(136003)(366004)(346002)(376002)(396003)(39860400002)(451199024)(1800799009)(186009)(1076003)(30864003)(8676002)(8936002)(4326008)(2616005)(5660300002)(26005)(83380400001)(41300700001)(478600001)(6512007)(38350700002)(316002)(38100700002)(52116002)(6506007)(36756003)(6486002)(86362001)(66946007)(6916009)(66556008)(66476007)(2906002)(6666004);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: AfiNZzIqNl+tnBbfD7ocv8ITCAUhfvL3Ik7XZ4BzrBdKrUf1M7D23oYu3eupEpqqnW3uZutVDnybvkjGJlYJUyKc10qD92ajyQIibUSE6dChDelaAUnNhCj1QJVWtisgGTOo1aZlLaOWUA/XMfXjAZUqCdkFbXpiwCm+m77TRjzeyH2n62pFTCpdiQ6Rq9prow6yga9PuEbaz9gIKABoj/E2szpP5DF5xGwEZuQSMp0prb7uUZVOGPxN6wgk1syBdVsnh+ew/yirHH25OouuY7hMznVrQm0/0f76/z2n/Upjyis/XbhIK6TztJOGsupya8SH7d1GMgQqpQwWPDIyH+4nJNOa3MYDt1ABzgQq3Yn6MzNAcY/9dep4iZnIUj5qsNiieLh41xg6wXN4n7xHA54LpecHAsIyKfnvWUAyDeE5fT4MROb3R1nZHV3RKcECkLtMuEIK2Wmsf8JTfUHyAY7lj/Zu6STJSupUu/GKofXiwmlaACVX208IABK7HcmjGguaV0QU+Ku0xM/fKQSpXv/XvqT4Hsf79Dke1v4rFdp/l5T9etT6CDiJzc2PaRfojcUhThGnl/IMFHOn4gY4+Wg9xQUZdfqK+Vr1oroC90/upXnYm6USzqlg7IKjaHKS+Cti1M/JRPQMTxcrWt4glA3VwdzeKKq8ZaLG2xrBuf/jpaAAov3AmvfgOlin6M9bJheZuIm9D5OiDr3hSTcXvKHBkbVWMowYgxW9fHgSodiD94ssSCZxwOz5vP9S7/yV59A08Wmb7tXUBO/eu4eWqpcU3rGLugBgz1tCBVnuiMmRHZ9qWexJMp2dsGArMZ7ycll69WlMWWRtqo0ndtFYXzYvZ1m5OlC9/7ogBq5+oq04ipn8rhv4EoQ6TMNuFvguDNUjpfx5zcJsqgvCq8D7BrMzE0dPhdxwClJinttKSsoteHatgj+z4VVl0knHKJEapx+U1jOB93PanY7dzXSey02lSieGOvG9qRsGhuXCbJJQF9CogUxSW6LVPTDJiQNLI3qV496qbA29fKypYI1ZDQuos4+XxtVq+YQ8IQ1alyalBlPrXyXC0Iu3Uf1wCIirsMkDvoBeBkDAXLjsW/5UuDujAgX3GmMas3j3D3w3tRv651ru/DkgD+SNrZvIp4tsplfRB1Yg7qnIMqC965YtK+VikGeeUkjiQ44I5rOm1hUrVJcJlNhOE95SBou/3OVX2klAzPjbICxPPUuu1qXFQ9rsneJJGum1ul2LBF6ib7tNATExhy7Y19igJ5a3Y4umqlYk29acvkaNGBcImJ8n63YNHIzqHedIgl+H7/zuRcvFj79ajrQi6GxmnrAH4mwopWunPtCk1kcxE0d/34Ak8x6s3RG3HMtTKygqCq3F3ms944bs2bS1CovLfpKbe+qgwwFhge31rsVdofRGNx7nZqllcRzNQhA0y+L9obA9/+xwC1cKJt9Y1PqGbsb3fvvqd2z3+4keGPy5K9loC//hKlrBNhlGWzKvMVcbtUEPB5+kfIEtrZ5rzHXQaXowH/82fK8Ix1nOyub8hzCmuvhgV4Bdm2cTyBHkd4iMaBq9yQOMbaJ9QWUhpRXwkvtd0nBk X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: fa96b242-ed03-45d4-dfc0-08dbae58905e X-MS-Exchange-CrossTenant-AuthSource: AM6PR04MB4838.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Sep 2023 21:39:20.8312 (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: zwjUp5nMRkjos5Nf5ey/uVSOXNaUBC4Pvla5vlmBFr6fg2I4ymBzsxGrQSkHMrNjIU6lIDpvJw7SBSLse81xwg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB8PR04MB6859 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230905_143927_820906_8C07DDC4 X-CRM114-Status: GOOD ( 23.87 ) 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 Add I3C slave mode and tty over i3c func driver document. Signed-off-by: Frank Li --- Documentation/driver-api/i3c/index.rst | 1 + .../driver-api/i3c/slave/i3c-slave-cfs.rst | 109 ++++++++++ .../driver-api/i3c/slave/i3c-slave.rst | 189 ++++++++++++++++++ .../driver-api/i3c/slave/i3c-tty-function.rst | 103 ++++++++++ .../driver-api/i3c/slave/i3c-tty-howto.rst | 109 ++++++++++ Documentation/driver-api/i3c/slave/index.rst | 13 ++ 6 files changed, 524 insertions(+) create mode 100644 Documentation/driver-api/i3c/slave/i3c-slave-cfs.rst create mode 100644 Documentation/driver-api/i3c/slave/i3c-slave.rst create mode 100644 Documentation/driver-api/i3c/slave/i3c-tty-function.rst create mode 100644 Documentation/driver-api/i3c/slave/i3c-tty-howto.rst create mode 100644 Documentation/driver-api/i3c/slave/index.rst diff --git a/Documentation/driver-api/i3c/index.rst b/Documentation/driver-api/i3c/index.rst index 783d6dad054b6..63fc51fc8bd58 100644 --- a/Documentation/driver-api/i3c/index.rst +++ b/Documentation/driver-api/i3c/index.rst @@ -9,3 +9,4 @@ I3C subsystem protocol device-driver-api master-driver-api + slave/index diff --git a/Documentation/driver-api/i3c/slave/i3c-slave-cfs.rst b/Documentation/driver-api/i3c/slave/i3c-slave-cfs.rst new file mode 100644 index 0000000000000..d78fcbc4e5587 --- /dev/null +++ b/Documentation/driver-api/i3c/slave/i3c-slave-cfs.rst @@ -0,0 +1,109 @@ +.. SPDX-License-Identifier: GPL-2.0 + +======================================= +Configuring I3C Slave Using CONFIGFS +======================================= + +:Author: Frank Li + +The I3C Slave Core exposes configfs entry (i3c_slave) to configure the I3C +slave function and to bind the slave function +with the slave controller. (For introducing other mechanisms to +configure the I3C Slave Function refer to [1]). + +Mounting configfs +================= + +The I3C Slave Core layer creates i3c_slave directory in the mounted configfs +directory. configfs can be mounted using the following command:: + + mount -t configfs none /sys/kernel/config + +Directory Structure +=================== + +The i3c_slave configfs has two directories at its root: controllers and +functions. Every Controller device present in the system will have an entry in +the *controllers* directory and every Function driver present in the system +will have an entry in the *functions* directory. +:: + + /sys/kernel/config/i3c_slave/ + .. controllers/ + .. functions/ + +Creating Function Device +=================== + +Every registered Function driver will be listed in controllers directory. The +entries corresponding to Function driver will be created by the Function core. +:: + + /sys/kernel/config/i3c_slave/functions/ + .. / + ... / + ... / + ... / + .. / + ... / + ... / + +In order to create a of the type probed by , +the user has to create a directory inside . + +Every directory consists of the following entries that can be +used to configure the standard configuration header of the slave function. +(These entries are created by the framework when any new is +created) +:: + + .. / + ... / + ... vendor_id + ... part_id + ... bcr + ... dcr + ... ext_id + ... instance_id + ... max_read_len + ... max_write_len + ... vendor_info + +Controller Device +========== + +Every registered Controller device will be listed in controllers directory. The +entries corresponding to Controller device will be created by the Controller +core. +:: + + /sys/kernel/config/i3c_slave/controllers/ + .. / + ... / + .. / + ... / + +The directory will have a list of symbolic links to +. These symbolic links should be created by the user to +represent the functions present in the slave device. Only +that represents a physical function can be linked to a Controller device. + +:: + + | controllers/ + | / + | + | functions/ + | / + | / + | vendor_id + | part_id + | bcr + | dcr + | ext_id + | instance_id + | max_read_len + | max_write_len + | vendor_info + +[1] Documentation/I3C/slave/pci-slave.rst diff --git a/Documentation/driver-api/i3c/slave/i3c-slave.rst b/Documentation/driver-api/i3c/slave/i3c-slave.rst new file mode 100644 index 0000000000000..363421241b594 --- /dev/null +++ b/Documentation/driver-api/i3c/slave/i3c-slave.rst @@ -0,0 +1,189 @@ +.. SPDX-License-Identifier: GPL-2.0 + +:Author: Frank Li + +This document is a guide to use the I3C Slave Framework in order to create +slave controller driver, slave function driver, and using configfs +interface to bind the function driver to the controller driver. + +Introduction +============ + +Linux has a comprehensive I3C subsystem to support I3C controllers that +operates in master mode. The subsystem has capability to scan I3C bus,assign +i3c device address, load I3C driver (based on Manufacturer ID, part ID), +support other services like hot-join, In-Band Interrupt(IBI). + +However the I3C controller IP integrated in some SoCs is capable of operating +either in Master mode or Slave mode. I3C Slave Framework will add slave mode +support in Linux. This will help to run Linux in an slave system which can +have a wide variety of use cases from testing or validation, co-processor +accelerator, etc. + +I3C Slave Core +================= + +The I3C Slave Core layer comprises 3 components: the Slave Controller +library, the Slave Function library, and the configfs layer to bind the +slave function with the slave controller. + +I3C Slave Controller Library +------------------------------------ + +The Controller library provides APIs to be used by the controller that can +operate in slave mode. It also provides APIs to be used by function +driver/library in order to implement a particular slave function. + +APIs for the I3C Slave controller Driver +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This section lists the APIs that the I3C Slave core provides to be used +by the I3C controller driver. + +* devm_i3c_slave_ctrl_create()/i3c_slave_ctrl_create() + + The I3C controller driver should implement the following ops: + + * set_config: ops to set i3c configuration + * enable: ops to enable controller + * disable: ops to disable controller + * raise_ibi: ops to raise IBI to master controller + * alloc_request: ops to alloc a transfer request + * free_request: ops to free a transfer request + * queue: ops to queue a request to transfer queue + * dequeue: ops to dequeue a request from transfer queue + * cancel_all_reqs: ops to cancel all request from transfer queue + * fifo_status: ops to get fifo status + * fifo_flush: ops to flush hardware fifo + * get_features: ops to get controller supported features + + The I3C controller driver can then create a new Controller device by + invoking devm_i3c_slave_ctrl_create()/i3c_slave_ctrl_create(). + +* devm_i3c_slave_ctrl_destroy()/i3c_slave_ctrl_destroy() + + The I3C controller driver can destroy the Controller device created by + either devm_i3c_slave_ctrl_create() or i3c_slave_ctrl_create() using + devm_i3c_slave_ctrl_destroy() or i3c_slave_ctrl_destroy(). + +I3C Slave Controller APIs for the I3C Slave Function Driver +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This section lists the APIs that the I3C Slave core provides to be used +by the I3C slave function driver. + +* i3c_slave_ctrl_set_config() + + The I3C slave function driver should use i3c_slave_ctrl_set_config() to + write i3c configuration to the slave controller. + +* i3c_slave_ctrl_enable()/i3c_slave_ctrl_disable() + + The I3C slave function driver should use i3c_slave_ctrl_enable()/ + i3c_slave_ctrl_disable() to enable/disable i3c slave controller. + +* i3c_slave_ctrl_alloc_request()/i3c_slave_ctrl_free_request() + + The I3C slave function driver should usei3c_slave_ctrl_alloc_request() / + i3c_slave_ctrl_free_request() to alloc/free a i3c request. + +* i3c_slave_ctrl_raise_ibi() + + The I3C slave function driver should use i3c_slave_ctrl_raise_ibi() to + raise IBI. + +* i3c_slave_ctrl_queue()/i3c_slave_ctrl_dequeue() + + The I3C slave function driver should use i3c_slave_ctrl_queue()/ + i3c_slave_ctrl_dequeue(), to queue/dequeue I3C transfer to/from transfer + queue. + +* i3c_slave_ctrl_get_features() + + The I3C slave function driver should use i3c_slave_ctrl_get_features() + to get I3C slave controller supported features. + +Other I3C Slave Controller APIs +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +There are other APIs provided by the Controller library. These are used for +binding the I3C Slave Function device with Controlller device. i3c-cfs.c can +be used as reference for using these APIs. + +* i3c_slave_ctrl_get() + + Get a reference to the I3C slave controller based on the device name of + the controller. + +* i3c_slave_ctrl_put() + + Release the reference to the I3C slave controller obtained using + i3c_slave_ctrl_get() + +* i3c_slave_ctrl_add_func() + + Add a I3C slave function to a I3C slave controller. + +* i3c_slave_ctrl_remove_func() + + Remove the I3C slave function from I3C slave controller. + +I3C Slave Function Library +---------------------------------- + +The I3C Slave Function library provides APIs to be used by the function driver +and the Controller library to provide slave mode functionality. + +I3C Slave Function APIs for the I3C Slave Function Driver +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This section lists the APIs that the I3C Slave core provides to be used +by the I3C slave function driver. + +* i3c_slave_func_register_driver() + + The I3C Slave Function driver should implement the following ops: + * bind: ops to perform when a Controller device has been bound to + Function device + * unbind: ops to perform when a binding has been lost between a + Controller device and Function device + + The I3C Function driver can then register the I3C Function driver by using + i3c_slave_func_register_driver(). + +* i3c_slave_func_unregister_driver() + + The I3C Function driver can unregister the I3C Function driver by using + i3c_epf_unregister_driver(). + +APIs for the I3C Slave Controller Library +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This section lists the APIs that the I3C Slave core provides to be used +by the I3C slave controller library. + +Other I3C Slave APIs +~~~~~~~~~~~~~~~~~~~~ + +There are other APIs provided by the Function library. These are used to +notify the function driver when the Function device is bound to the EPC device. +i3c-cfs.c can be used as reference for using these APIs. + +* i3c_slave_func_create() + + Create a new I3C Function device by passing the name of the I3C EPF device. + This name will be used to bind the Function device to a Function driver. + +* i3c_slave_func_destroy() + + Destroy the created I3C Function device. + +* i3c_slave_func_bind() + + i3c_slave_func_bind() should be invoked when the EPF device has been bound + to a Controller device. + +* i3c_slave_func_unbind() + + i3c_slave_func_unbind() should be invoked when the binding between EPC + device and function device is lost. diff --git a/Documentation/driver-api/i3c/slave/i3c-tty-function.rst b/Documentation/driver-api/i3c/slave/i3c-tty-function.rst new file mode 100644 index 0000000000000..3c8521d7aa31a --- /dev/null +++ b/Documentation/driver-api/i3c/slave/i3c-tty-function.rst @@ -0,0 +1,103 @@ +.. SPDX-License-Identifier: GPL-2.0 + +================= +PCI Test Function +================= + +:Author: Kishon Vijay Abraham I + +Traditionally PCI RC has always been validated by using standard +PCI cards like ethernet PCI cards or USB PCI cards or SATA PCI cards. +However with the addition of EP-core in linux kernel, it is possible +to configure a PCI controller that can operate in EP mode to work as +a test device. + +The PCI endpoint test device is a virtual device (defined in software) +used to test the endpoint functionality and serve as a sample driver +for other PCI endpoint devices (to use the EP framework). + +The PCI endpoint test device has the following registers: + + 1) PCI_ENDPOINT_TEST_MAGIC + 2) PCI_ENDPOINT_TEST_COMMAND + 3) PCI_ENDPOINT_TEST_STATUS + 4) PCI_ENDPOINT_TEST_SRC_ADDR + 5) PCI_ENDPOINT_TEST_DST_ADDR + 6) PCI_ENDPOINT_TEST_SIZE + 7) PCI_ENDPOINT_TEST_CHECKSUM + 8) PCI_ENDPOINT_TEST_IRQ_TYPE + 9) PCI_ENDPOINT_TEST_IRQ_NUMBER + +* PCI_ENDPOINT_TEST_MAGIC + +This register will be used to test BAR0. A known pattern will be written +and read back from MAGIC register to verify BAR0. + +* PCI_ENDPOINT_TEST_COMMAND + +This register will be used by the host driver to indicate the function +that the endpoint device must perform. + +======== ================================================================ +Bitfield Description +======== ================================================================ +Bit 0 raise legacy IRQ +Bit 1 raise MSI IRQ +Bit 2 raise MSI-X IRQ +Bit 3 read command (read data from RC buffer) +Bit 4 write command (write data to RC buffer) +Bit 5 copy command (copy data from one RC buffer to another RC buffer) +======== ================================================================ + +* PCI_ENDPOINT_TEST_STATUS + +This register reflects the status of the PCI endpoint device. + +======== ============================== +Bitfield Description +======== ============================== +Bit 0 read success +Bit 1 read fail +Bit 2 write success +Bit 3 write fail +Bit 4 copy success +Bit 5 copy fail +Bit 6 IRQ raised +Bit 7 source address is invalid +Bit 8 destination address is invalid +======== ============================== + +* PCI_ENDPOINT_TEST_SRC_ADDR + +This register contains the source address (RC buffer address) for the +COPY/READ command. + +* PCI_ENDPOINT_TEST_DST_ADDR + +This register contains the destination address (RC buffer address) for +the COPY/WRITE command. + +* PCI_ENDPOINT_TEST_IRQ_TYPE + +This register contains the interrupt type (Legacy/MSI) triggered +for the READ/WRITE/COPY and raise IRQ (Legacy/MSI) commands. + +Possible types: + +====== == +Legacy 0 +MSI 1 +MSI-X 2 +====== == + +* PCI_ENDPOINT_TEST_IRQ_NUMBER + +This register contains the triggered ID interrupt. + +Admissible values: + +====== =========== +Legacy 0 +MSI [1 .. 32] +MSI-X [1 .. 2048] +====== =========== diff --git a/Documentation/driver-api/i3c/slave/i3c-tty-howto.rst b/Documentation/driver-api/i3c/slave/i3c-tty-howto.rst new file mode 100644 index 0000000000000..11c8900fd16f3 --- /dev/null +++ b/Documentation/driver-api/i3c/slave/i3c-tty-howto.rst @@ -0,0 +1,109 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=================== +I3C TTY User Guide +=================== + +:Author: Frank Li + +This document is a guide to help users use i3c-slave-tty function driver +and i3ctty master driver for testing I3C. The list of steps to be followed in the +master side and slave side is given below. + +Endpoint Device +=============== + +Endpoint Controller Devices +--------------------------- + +To find the list of slave controller devices in the system:: + + # ls /sys/class/i3c_slave/ + 44330000.i3c-slave + +If CONFIG_I3C_SLAVE_CONFIGFS is enabled:: + + # ls /sys/kernel/config/i3c_slave/controllers/ + 44330000.i3c-slave + + +Endpoint Function Drivers +------------------------- + +To find the list of slave function drivers in the system:: + + # ls /sys/bus/i3c_slave_func/drivers + tty + +If CONFIG_I3C_SLAVE_CONFIGFS is enabled:: + + # ls /sys/kernel/config/i3c_slave/functions + tty + + +Creating i3c-slave-tty Device +---------------------------- + +I3C slave function device can be created using the configfs. To create +i3c-slave-tty device, the following commands can be used:: + + # mount -t configfs none /sys/kernel/config + # cd /sys/kernel/config/i3c_slave/ + # mkdir functions/tty/func1 + +The "mkdir func1" above creates the i3c-slave-tty function device that will +be probed by i3c tty driver. + +The I3C slave framework populates the directory with the following +configurable fields:: + + # ls functions/tty/func1 + bcr dcr ext_id instance_id max_read_len max_write_len + part_id vendor_id vendor_info + +The I3C slave function driver populates these entries with default values +when the device is bound to the driver. The i3c-slave-tty driver populates +vendorid with 0xffff and interrupt_pin with 0x0001:: + + # cat functions/tty/func1/vendor_id + 0x0 + +Configuring i3c-slave-tty Device +------------------------------- + +The user can configure the i3c-slave-tty device using configfs entry. In order +to change the vendorid, the following commands can be used:: + + # echo 0x011b > functions/tty/func1/vendor_id + # echo 0x1000 > functions/tty/func1/part_id + # echo 0x6 > functions/tty/t/bcr + +Binding i3c-slave-tty Device to slave Controller +------------------------------------------------ + +In order for the slave function device to be useful, it has to be bound to +a I3C slave controller driver. Use the configfs to bind the function +device to one of the controller driver present in the system:: + + # ln -s functions/pci_epf_test/func1 controllers/44330000.i3c-slave/ + +I3C Master Device +================ + +Check I3C tty device is probed + + # ls /sys/bus/i3c/devices/0-23610000000 + 0-23610000000:0 bcr dcr driver dynamic_address hdrcap + modalias pid power subsystem tty uevent + +Using Slave TTY function Device +----------------------------------- + +Host side: + cat /dev/ttyI3C0 +Slave side + echo abc >/dev/ttyI3C0 + +You will see "abc" show at console. + +You can use other tty tool to test I3C slave tty device. diff --git a/Documentation/driver-api/i3c/slave/index.rst b/Documentation/driver-api/i3c/slave/index.rst new file mode 100644 index 0000000000000..69727ccf985db --- /dev/null +++ b/Documentation/driver-api/i3c/slave/index.rst @@ -0,0 +1,13 @@ +.. SPDX-License-Identifier: GPL-2.0 + +====================== +I3C Slave Framework +====================== + +.. toctree:: + :maxdepth: 2 + + i3c-slave + i3c-slave-cfs + i3c-tty-howto +