From patchwork Mon Jan 29 19:53:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Li X-Patchwork-Id: 767673 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2056.outbound.protection.outlook.com [40.107.104.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F09967605A; Mon, 29 Jan 2024 19:53:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.104.56 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706558033; cv=fail; b=oBTBGkEkgMRTyQPcZAOaLWO2uyGa65qn4eQUap3YuQNLqymlL+roUVOACjot7MAGpsIDk0oCSDDfT6N0XXi7Onyku8kOqbik4oLpei9TuAPpeHZk5dF6dry8Ifz7r42Dk/G8B2SVYrxXURgrH5c5frXZK0uWmCYSohWSTAo9A98= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706558033; c=relaxed/simple; bh=xUss3csYfHdCltrg+pFxqrfdbvboutFgGbf1Juggzig=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: Content-Type:MIME-Version; b=lIa+vx6nqdxXGGy+hbInwbA0FzgQeDKrcbI96srdWQwMnX9MohfAc85qqPOoJ8Vxc2WmSn5RYqaPgKFiamDXrHQYORtDWtJaMrc4adLkVk07YC9/Qfg/bHhprRACJYHUuyJHPsziCcCvkYUJVMkgx6IXvex+mXIGjcB5lkpj7kI= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com; spf=pass smtp.mailfrom=nxp.com; dkim=pass (1024-bit key) header.d=nxp.com header.i=@nxp.com header.b=Y5odScM4; arc=fail smtp.client-ip=40.107.104.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nxp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=nxp.com header.i=@nxp.com header.b="Y5odScM4" ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=NP31FGBRw3H7pUsp5h9CRf3SDtT1+HXy8u7GMkTZKxwg659IZ1U3JFW9z38z0CcTTHnCUCUyASyS/Uozc6W4b0Hhk663cA3JHQlGc5V4QN1iqIWR4rGEOO2+6aQLJb6cwQtfsdklpVlUfsVpH74ropt6rJNB5ZrcI7NKs8b8TknQgowBIbELSGWXr4y2IiTJV55CXEJaKfOIexFB6nHCOWUskPhFGZHUcPNMJjNiwta3MWuqiE11OT0Qg5qZNvZruaWBTDKJgwIunft5DVKrASuUM+sg2bwUFUIZOis/XQr/oOxCKVkiZsxu12gILZJ7vbVU2y5G+rfQSGZ1h8lOXA== 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=eeFeSa6EDN9RUHWjHYeb4cCKIA0/LO0G9GX7zxcsJ/8=; b=l/DNqPBr20Dg3ynHEoyaXlgAir2tVTtmWdjt1KWE4ostMFkotEcR7PNntuo7XKIQ1fl3t7fv70DHFHqEoAk9FB/YaIFuAZv5cRGCJdos1UQO3WTxDU/0cWYK9lEjz/HLyt0pfZZPTA4kNZeiQpxqYp2PiM08MW/Vshog28dQ6m2CgxYG0H67LZJcZ520Ev5tQ9B4oyhYXZsX7kur5yqacIdT+oy5o02EZoOOc/3VdjG6BdJjZzTNOxpbmeyPC0yPovqBg0OvifoZfb/HaIZDFv7/TOKaA8rpie6h6ndr+uqDboZZUx/U6DTkMRr/PJT+MHFlvbvL4VWoHU3l3jyyDw== 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=eeFeSa6EDN9RUHWjHYeb4cCKIA0/LO0G9GX7zxcsJ/8=; b=Y5odScM4BgiahqVopNXdqcUq+tT2FNRjNuNdfwW3uR/ec6lj2f2wKk+LWHmnyT8pFmU4IO0jJTuMU5clSvqr4bJX5+tSZRVpJwp2xDFM8NQLsfR3eQ4uzGov3rqla/wVgOh75HAN81TuXAN+KiPC9bTedegLgj8SAclQtrfT0gQ= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from PAXPR04MB9642.eurprd04.prod.outlook.com (2603:10a6:102:240::14) by PAXPR04MB8128.eurprd04.prod.outlook.com (2603:10a6:102:1c8::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.32; Mon, 29 Jan 2024 19:53:48 +0000 Received: from PAXPR04MB9642.eurprd04.prod.outlook.com ([fe80::c8b4:5648:8948:e85c]) by PAXPR04MB9642.eurprd04.prod.outlook.com ([fe80::c8b4:5648:8948:e85c%3]) with mapi id 15.20.7228.029; Mon, 29 Jan 2024 19:53:48 +0000 From: Frank Li To: ilpo.jarvinen@linux.intel.com Cc: Frank.Li@nxp.com, alexandre.belloni@bootlin.com, conor.culhane@silvaco.com, devicetree@vger.kernel.org, gregkh@linuxfoundation.org, imx@lists.linux.dev, jirislaby@kernel.org, joe@perches.com, krzysztof.kozlowski+dt@linaro.org, krzysztof.kozlowski@linaro.org, linux-i3c@lists.infradead.org, linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, miquel.raynal@bootlin.com, robh@kernel.org, zbigniew.lukwinski@linux.intel.com Subject: [PATCH v5 2/8] dt-bindings: i3c: svc: add proptery mode Date: Mon, 29 Jan 2024 14:53:15 -0500 Message-Id: <20240129195321.229867-3-Frank.Li@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240129195321.229867-1-Frank.Li@nxp.com> References: <20240129195321.229867-1-Frank.Li@nxp.com> X-ClientProxiedBy: BYAPR05CA0091.namprd05.prod.outlook.com (2603:10b6:a03:e0::32) To PAXPR04MB9642.eurprd04.prod.outlook.com (2603:10a6:102:240::14) Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PAXPR04MB9642:EE_|PAXPR04MB8128:EE_ X-MS-Office365-Filtering-Correlation-Id: 1a82e300-5367-4f87-5f68-08dc2104024d X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: arPb0NWLbur7M4/ijJRDqbnPr18boJVLBw9VdaqvLycGEKli6vjCN59p5KF3sT+HdXkgl9a2Hvt88jo7ukDMlxlXsz8DsZQl1SEi0d+iZfjzqDmm7bKg3lycDtVs1rUvwq/uQqiCpaRU0EumH8cVqhZ6aRmeB1wKxsnA2PdBMzsZ2sUssb+NH7kCp00GQn6a+f5XU6p10f5df9JnjwYNA6moOKfboqq3yUAf6nnf5DVwQViJfdbg4XV63ZP41hmQrdTHJ8I5AGeXg7sOpq1HSSr+m/jNT8yXHgxcaNlrF7Y3xrD0xzYPppZpQv0mKxCcrbo/wV5WzopuArQnnUs6+LDmSxOseOY5L+T1RUcsOVs5OcKAnWsnHzXsceCYNcrnfChYmouslKQWBQrMVLUdf6fdy3p4kDwCoNvrBPTUtIpHr7XYZTc4DTNN/s+9SAbZOdq+M90JnQoRBUvId5Dk9Bq4sAYgXitTWQP24qIEtUpPLFnokCELT1Hvl3Cy/gB32HBxGFqgciMGCWF8PinAG6HgggqF3MirW3EkW7iQce2q20KjVFTQfRnwzY2rOrgKayqeRSqM9vHVSXAQbyxL1bzZJTxoVMOfm4w5+0/g2Gs= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PAXPR04MB9642.eurprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(376002)(39860400002)(136003)(366004)(346002)(396003)(230922051799003)(451199024)(1800799012)(186009)(64100799003)(1076003)(26005)(52116002)(83380400001)(6512007)(6666004)(6506007)(38100700002)(66946007)(4326008)(5660300002)(8936002)(8676002)(7416002)(41300700001)(2616005)(966005)(316002)(478600001)(6916009)(2906002)(66476007)(6486002)(66556008)(86362001)(36756003)(38350700005); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 1MmUk/2gBc2v7nPYPPDPo+fFQReEramfKqmEDROP1MV/qQKBH1HAOQ96kKB5eNIczvu83Gk6svocR3xQoBm9AdDNa7AacWBftsATtt4taBs7ei+iWrmlDcvhl4mgYdR69oUnF9ddYb49sdnVY1K6U0DU4CkC8WzCTjqealkT5nxNdRGRfHN/YgJ2OLSBYW2m+OTwjR8VuNJjCXzbdf4Ov2uaftklwiI3iaiBUNoMsADS+cR2fVdOJV9yhLFuhVlO8gE9UTTUdr5seEJZ/ts3KlxP0yq9ijFlo2NEZCFCVVfMkf6MNBCEEgOTHmBnSmv8259ZlluNaubsBrpnTkgNbKM6dN6eytDx+LEYY2jH0PGalwsaImkqQFQBdamIurfBLup7mjzkMJO1uo00sVCYco+/+uBdqHU5elAfHK/v2r7IV4elaOOcTEth2Ya8h/HUWe7nS0AcVnIUQqd8KuTXyhdlZQFl3Kr0HyBx3o6o7tmdFUXruzO9X540FXmj3Jv2UyjVTtLd/6pPD0f0/R6n3cXF+qYqYmS+C70X2Y5hmHk8B3DQv8FsAIjlkCdzpkkvyY4b4fyOYCM7QSxGNcjU1M6Z4rx5xxp+LNHlsCNs0XpmAe+18MLfYvB2eQ4e3p5dHYqBf6/hMiF2R2Vo+nDBDkkKTWoVVEfYxe4ixgCoSyxL/mXWnBi5TRCD7XOTdHt14t1aV5ZGKy4f7n0oTfnW1ZABS2G78XTP5M6ze6r5BZCRAZbulpWSkqxIBvCXdTQ+fxUOvGvRLfBzynXth7aHVGXKTM7hnWSibhLuA2m4Q7uXcst7uTHi7Xu2kVwGMU5cibCkaCVZlupi40SIWQcNQEJiEMfsxQLgL1d28SvowUbL1ScwCkUkz5uSYQ1ARUprJsxVvRYMiUIrwq59zlUPQdhLEYrkdF5qiwp6WBHuZ6dUxgzIuq3CKSPIIlB3WiAJrRYVcasvzMH8y4EDpCn/371LtBwneVOBAct0H7zPViF8g8FVb5W1ZcwEwsOA5VXMJS/q8Gcq3yyYo/KD8N549pOecypoC85uJFtSt+p81Tn1rOSb+CAs/xYA1rINZ4Oa8qGAeJ4SF8wJQydFdenG/PRiwqLeySdXw8V9n7+kmsI6fkycxDRgOREHeU0rVArMaMBeUypvzVnZVWjCd9oe/sp6R6W46qX0ItG6MKcU3pLsxbhUNt63heKYAoY9ME3FqbnegslDkJOslEJnh1fz8D8Tl5NUaLij0cTNSo+kS8RCeEGMGas4Y4eU0bI/dcd+C7rLRSZGtZJKj7ShbllXKCtWmAvFKvL1SI3b0CxJi4jT9evY/kheJwEy1HoA8ZRewIjXd72Uw211kSAwjqVCfUu5PXAVs0ZCGXv6AoJj4qVtFKYWqLY8WX2ki2dfG5sKRSOmnwJn2Hjxa3d3CRHtD7rQnFYkaDjByYAimW3JPKHUkMzjAL7oqRuRVz07W3xgZjYL0/xxoQ0oCX0pem5gVcH0wcBSwH7Q0bTuidu992c74c3Ip2BqI6V1qIeb+tKUCfBYbJKxG8y4FVgz4Rt47MRZDM0+JcCUFQSnF5xzmUdv+R5Onbzyk3a84v5tr0xG X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1a82e300-5367-4f87-5f68-08dc2104024d X-MS-Exchange-CrossTenant-AuthSource: PAXPR04MB9642.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Jan 2024 19:53:48.3491 (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: MxeDlddS14rcqBoe8WoKDuOoZcVEej3vVnrrZiAfZiai+ZoEaegP+IOvt3hvkKRBlE8vVO94dw0jKvIH/H7z+A== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB8128 Add 'mode' property to distinguish between 'controller' and 'target' modes. Signed-off-by: Frank Li Reviewed-by: Krzysztof Kozlowski --- Notes: Change from v3 to v4 -fix dtb check error Change from v2 to v3 - using 'mode' distringuish master and target mode .../devicetree/bindings/i3c/silvaco,i3c-master.yaml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/i3c/silvaco,i3c-master.yaml b/Documentation/devicetree/bindings/i3c/silvaco,i3c-master.yaml index 133855f11b4f5..3af77d143f018 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/target maintainers: - Conor Culhane @@ -22,6 +22,15 @@ properties: interrupts: maxItems: 1 + mode: + description: + Tells Dual-Role I3C controllers that we want to work on a particular + mode. In case this attribute isn't passed via DT, I3C controllers + should default to 'controller'. + $ref: /schemas/types.yaml#/definitions/string + enum: [controller, target] + default: controller + clocks: items: - description: system clock From patchwork Mon Jan 29 19:53:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Li X-Patchwork-Id: 767672 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on2076.outbound.protection.outlook.com [40.107.104.76]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 238F5157050; Mon, 29 Jan 2024 19:53:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.104.76 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706558041; cv=fail; b=sJ7WXX6aVkso4c0rzcHFg/u1N3jlgnVHYrlNO19v3ldplQY/fEl6KbHkzas0MUUMviSyt/dlkekm4eJurjwOlxDIiectnBqb0CvEvkhwVrtoy3oPwK+kwjH0JbrjmQy8PyvpVEHynIBiyQ0jzoOfL3R+KpmnnNtAmVopdpu/eNo= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706558041; c=relaxed/simple; bh=or+397yWvEm61Xp5s78xEs1alVCqW+LonSzHmBaw9VM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: Content-Type:MIME-Version; b=CtJ6Q7MwsoGJrs+cnBwhpp8NTHBIdHTF520LGSRgw9OwybowShM6rgd8hR1ppniomNFVQpIp2K6Q8koRU6IKJhmX9NJbW/4vRB4nv70ugfcFF/u0uY02wFODFGu+HUutZyv05QloKeSSO8/RFenXrze9D0tcoOM9POH9d7bmtU0= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com; spf=pass smtp.mailfrom=nxp.com; dkim=pass (1024-bit key) header.d=nxp.com header.i=@nxp.com header.b=FlT29xD/; arc=fail smtp.client-ip=40.107.104.76 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nxp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=nxp.com header.i=@nxp.com header.b="FlT29xD/" ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=IKcUQm1/YiKVZqr5hQIuSzKhIXMTAjoKSzlodSh9m9auwq67JdzO3UoPJ4IZHSiyngdPHhJfAWtkolJbnNHClTaD1jEMokZrqT3W36O8h9G8+MSEJ8IO/eBX9PYvH3sfWhUTUocvPkrS0k0qMSlSDWwTiOLX4WYnNBCKc4MjmaVfC4dxdSHYQ8kIF4i+Add1YaEo1SeXFdbaqGChAuqIhwjkYgHooWXTFtrRpYJhapjXEdTenH59N+Xrz5T4VAscY848w7G0JSKuWq+r1NQjQAGSkKFbPDrdJ1GFfnH5jXDll3eyQyVQyfa02YufbIsLPCt88Fe+ndu1UG0/aFSGvw== 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=XUFNo4LWNJOIgV/97UbyKVahyaF8RY8BcXYiK1q7NkA=; b=Z5yYr0xW2qJx/4pDY2RfD+sGYAaVaC44RSc23wFk/IQSM+h+mXD/1KrqcL2RFUDs0KLe6M7ZRvku6uCU7j+2QRCaRMyiUvOC5KDGy+Nefs4/SN1ZKpfVM5iMUMO5g7BdH+1Fbl/cF0wBuQh7jjkUF+dYoCHEGSh9kscs4TSz2ffXsH7VtuGbp4AWwwqRvSO8XINoxvf/ao22o1lBppgEDkR3xxUDi20j+hL/w9K0wWcR0X7l5qRbA0NrNDAHDINLWQkyGSr4YBGP7vit4AuaseXWBHPKvwoGOSqV+LVRjG9q16JLyGI/ulsgG1ghfLLuKJxycBYp9+Wz9imbowMrrA== 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=XUFNo4LWNJOIgV/97UbyKVahyaF8RY8BcXYiK1q7NkA=; b=FlT29xD/Nyya+mHJ27/4pw2HZ1Lk1sJQjuphrtnoDEfePEsfVr9K7EvYcCYcJRagCvaNQgKS50XQFdQ6gTpOSDXGWQRW5tLo3WO08T5IIuSdwZblbT3XZjxrvhdvsI9XOCRqcMwl+OSx5csICBBJYK24FADEQlQPbgoUCH+OIUI= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from PAXPR04MB9642.eurprd04.prod.outlook.com (2603:10a6:102:240::14) by PAXPR04MB8128.eurprd04.prod.outlook.com (2603:10a6:102:1c8::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.32; Mon, 29 Jan 2024 19:53:56 +0000 Received: from PAXPR04MB9642.eurprd04.prod.outlook.com ([fe80::c8b4:5648:8948:e85c]) by PAXPR04MB9642.eurprd04.prod.outlook.com ([fe80::c8b4:5648:8948:e85c%3]) with mapi id 15.20.7228.029; Mon, 29 Jan 2024 19:53:56 +0000 From: Frank Li To: ilpo.jarvinen@linux.intel.com Cc: Frank.Li@nxp.com, alexandre.belloni@bootlin.com, conor.culhane@silvaco.com, devicetree@vger.kernel.org, gregkh@linuxfoundation.org, imx@lists.linux.dev, jirislaby@kernel.org, joe@perches.com, krzysztof.kozlowski+dt@linaro.org, krzysztof.kozlowski@linaro.org, linux-i3c@lists.infradead.org, linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, miquel.raynal@bootlin.com, robh@kernel.org, zbigniew.lukwinski@linux.intel.com Subject: [PATCH v5 4/8] i3c: svc: Add svc-i3c-main.c and svc-i3c.h Date: Mon, 29 Jan 2024 14:53:17 -0500 Message-Id: <20240129195321.229867-5-Frank.Li@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240129195321.229867-1-Frank.Li@nxp.com> References: <20240129195321.229867-1-Frank.Li@nxp.com> X-ClientProxiedBy: BYAPR05CA0091.namprd05.prod.outlook.com (2603:10b6:a03:e0::32) To PAXPR04MB9642.eurprd04.prod.outlook.com (2603:10a6:102:240::14) Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PAXPR04MB9642:EE_|PAXPR04MB8128:EE_ X-MS-Office365-Filtering-Correlation-Id: 8a100bb0-cc18-444a-7402-08dc21040726 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: K40OkAdM82Aj9YJVCPKJfaJORA+ms735LnC15XbfbF5uLz8gVv2Hvnj7v8foEf4AUqT+4qcV+yFdTBtyf4V5+odr4VVyoZHDXW56VHex5gmeR5atkMHkACskE2mmGNVQRt/yutudY145XolKTCZGKrquEiv30dyQxLzoRRT9UMNaAScCEWkIDCwSKUx76jg+i/VN4BoRAwGUVckrt5Cu22xk/1jHIR95d5qGy8SJR3jAgr+9yl7g0y2lUIvGQOws0yUkec108qRTbzsA7vvs0ZXi9aRPJQOnCAGLViFqlXksc3rGUT7Jf8qXcG7klGaC35Ne/KdQzSnhxIt1++szHhkD0FyWObJiUE2CR2W7EKjYpNjmcQRcqcCFtMK7ZCEdGaBDWHG1r0y0dXh7Av+BdzyxgeQsGy1SqIAeFCpEXg31880RvcRMjFuXyLiKFncyd3f+3hrumbHIXOL+krl02EH7/t1J/P64y+yaW+4OOWBpY3rtxobSQeu0Ng6znbzryB7AQ6wbDy8xjuHrk5DPeMVg5a5SK7lQVZrvuIjMHYw5I+MhI/jE0ospBWVbNqd6WTMEPkpSBwEpWqwihYmzRFReIcyZXKS3c6oyd52PAWA= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PAXPR04MB9642.eurprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(376002)(39860400002)(136003)(366004)(346002)(396003)(230922051799003)(451199024)(1800799012)(186009)(64100799003)(1076003)(26005)(52116002)(83380400001)(6512007)(6666004)(6506007)(38100700002)(66946007)(4326008)(5660300002)(8936002)(8676002)(7416002)(41300700001)(2616005)(316002)(478600001)(6916009)(2906002)(66476007)(6486002)(66556008)(86362001)(36756003)(38350700005); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: D6j/Zd/y2E4EUHXYEQHIwmX6XkQfMmeSlc2kLOdu0orOu8kfCNGi375E3wy4A2BJX7dHsctifCEAYR0DSNF6MpAqyWxE8PzSn+IgcAubqtimFsxkJapMHNYlMYPKX1ZFs6fP/tm5mdE8iBG3CH10F65YR52DavNKuX+Wo9xbU7/cId7gpNu5sUPW1YJi2MXccHzrdUUxO1E/jCNMR8yRtoxIh63a8WyJEOnzlpa3BFECdBIyjpUzJ20Oq/d+RqboV3HPFp5HJ1tRCCYigc5ITDJndND+ZRPbJJs9wLXhsm8whlEAQavEIkgVo2jFCuV/raW3FEoJ9dGbyRK3usb+8LDd0cWKCwH2tcWOytlrp/FjtUqHLyIuMuRew/U9uOlD9vMZSsR+D3m0q8Yy0mLpXCx9fXpnSx8+e64pwgjFbDOrMjQCViWnKBl/QsOhzBgacYjaaxZmKTAiVIVkQVi0qq3hlsgC6qkpk8ZbX7Eqyg8BKsRHOBgZAoiMTiNnYpJjdIkJvdhrQhC5f4pMSqw8Diangeo7LMIY/1xtU5aLsmtDPNGbLZPkBLxf8+buOnorP16mqN2NkyBM+8d0jZsgrrEVOGK0a+QvC/JZudhXX3BKceJYQMt9GqtU572PWkdLGL31t1naxIhygWtljc+W3T1PS1SGPtlOEOSGuhgJN8DMUxhvmr+g2CdebUOwrUdjdX0kpNz/quYqsXgBXacPvcg0pwiKPMaB0AkOgMuwnbjLx2um0Q7tG7a9Ey7l34RxMFctDTilZKbGj4gg040D8XtCCT8Lu2JmEWS4fwk7frdSm/6eRFTG+hisbodax+EBLoRuRP+ZbI+e7cwx1iDRAGEEc+2a6psFWhBzSVz/EXK8b1b4dagAYQbQ8Npp9ZC7NnElGScUbdnz8zIYplqT703DJV3/7okYi4SIg9VvRFCtzGjz8ApwzGIO2leQhRZC7FJMvvq4+rMc7UGFb29Nq3FA/7yqSCM+uiaglQCC4uLkMp4DhgC1UV9V0OlBSmV5u8fb9hLIwZiCQDCDOYrt4vPWML/PL90KyGbdSS5VEDlHZpRoXX7lA3dyLuN5cOyPZ4uoHoNs1qjnpQLPvhteuspcrtFHFWYgxb6xY5UUeXcdT8HQbV/w5PyJqvjC+01ksLqO7Pv9VgZmCm61mzLdYswMfZLGSMgF7wVSkcJo5WX86hRFtRU3BSsnzrysi47u3Z8Kz6WzB1EWkLXFDHa3QItu84T2cNkYHGimw3WVRMJYuHPnt1s+2LfK+R9N8Stms4yYEcoADnwlKNiyz+15AJu6rBATknHXhkp+x9nAVerVvLD1F+c6rxwTT0MIV1OY270tMaGB3AG4Jdr0bX+mB7FQ7e2o1xsWcAcawloXvZB03gsDRfO2EYxIQLO0DZ7YnjOqQ6cmjCiOdzaR3p50dfi7EspZBovIDnVg9PcXwhHZrXje74kT2pFsPm/7AEkb0x9PZGAIvDWJlO+UC7H6zPNvTnCiYF1LEp9mH0FX9dlR591tzkFz0SDQINuXAMvcUJxduWdSU+/4V04dTPJGWYGj+gt69wErUcmng7C3fwj9S+DoptBhYE+lS+qDrPP1 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8a100bb0-cc18-444a-7402-08dc21040726 X-MS-Exchange-CrossTenant-AuthSource: PAXPR04MB9642.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Jan 2024 19:53:56.5271 (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: 2WchcXB5bB3m1GmhtmsyvtvI39IUKH821r1xLcJT2U7hhMly5comIokZlFqwmXSEDKPBFclNy+612cKx2M3H4g== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB8128 SVC i3c is a dual role controller. Move probe() into svc-i3c-main.c. This prepares to support target probe depending on dts "mode" settings. Signed-off-by: Frank Li --- Notes: Change from v4 to v5 - add new line at end of file New file from v4 drivers/i3c/master/Makefile | 3 +- drivers/i3c/master/svc-i3c-main.c | 53 +++++++++++++++++++++++++++++ drivers/i3c/master/svc-i3c-master.c | 34 ++++-------------- drivers/i3c/master/svc-i3c.h | 12 +++++++ 4 files changed, 73 insertions(+), 29 deletions(-) create mode 100644 drivers/i3c/master/svc-i3c-main.c create mode 100644 drivers/i3c/master/svc-i3c.h diff --git a/drivers/i3c/master/Makefile b/drivers/i3c/master/Makefile index 3e97960160bc8..484cb81f45821 100644 --- a/drivers/i3c/master/Makefile +++ b/drivers/i3c/master/Makefile @@ -2,5 +2,6 @@ obj-$(CONFIG_CDNS_I3C_MASTER) += i3c-master-cdns.o obj-$(CONFIG_DW_I3C_MASTER) += dw-i3c-master.o obj-$(CONFIG_AST2600_I3C_MASTER) += ast2600-i3c-master.o -obj-$(CONFIG_SVC_I3C_MASTER) += svc-i3c-master.o +svc-i3c-objs += svc-i3c-main.o svc-i3c-master.o +obj-$(CONFIG_SVC_I3C_MASTER) += svc-i3c.o obj-$(CONFIG_MIPI_I3C_HCI) += mipi-i3c-hci/ diff --git a/drivers/i3c/master/svc-i3c-main.c b/drivers/i3c/master/svc-i3c-main.c new file mode 100644 index 0000000000000..6be6a576cdf7a --- /dev/null +++ b/drivers/i3c/master/svc-i3c-main.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include + +#include "svc-i3c.h" + +static int svc_i3c_probe(struct platform_device *pdev) +{ + return svc_i3c_master_probe(pdev); +} + +static void svc_i3c_remove(struct platform_device *pdev) +{ + svc_i3c_master_remove(pdev); +} + +static int __maybe_unused svc_i3c_runtime_suspend(struct device *dev) +{ + return svc_i3c_master_runtime_suspend(dev); +} + +static int __maybe_unused svc_i3c_runtime_resume(struct device *dev) +{ + return svc_i3c_master_runtime_resume(dev); +} + +static const struct dev_pm_ops svc_i3c_pm_ops = { + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) + SET_RUNTIME_PM_OPS(svc_i3c_runtime_suspend, + svc_i3c_runtime_resume, NULL) +}; + +static const struct of_device_id svc_i3c_master_of_match_tbl[] = { + { .compatible = "silvaco,i3c-master-v1"}, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, svc_i3c_master_of_match_tbl); + +static struct platform_driver svc_i3c_master = { + .probe = svc_i3c_probe, + .remove_new = svc_i3c_remove, + .driver = { + .name = "silvaco-i3c-master", + .of_match_table = svc_i3c_master_of_match_tbl, + .pm = &svc_i3c_pm_ops, + }, +}; +module_platform_driver(svc_i3c_master); + diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c index 5ee4db68988e2..4dfe85ab17fd2 100644 --- a/drivers/i3c/master/svc-i3c-master.c +++ b/drivers/i3c/master/svc-i3c-master.c @@ -21,6 +21,8 @@ #include #include +#include "svc-i3c.h" + /* Master Mode Registers */ #define SVC_I3C_MCONFIG 0x000 #define SVC_I3C_MCONFIG_MASTER_EN BIT(0) @@ -1613,7 +1615,7 @@ static void svc_i3c_master_unprepare_clks(struct svc_i3c_master *master) clk_disable_unprepare(master->sclk); } -static int svc_i3c_master_probe(struct platform_device *pdev) +int svc_i3c_master_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct svc_i3c_master *master; @@ -1706,7 +1708,7 @@ static int svc_i3c_master_probe(struct platform_device *pdev) return ret; } -static void svc_i3c_master_remove(struct platform_device *pdev) +void svc_i3c_master_remove(struct platform_device *pdev) { struct svc_i3c_master *master = platform_get_drvdata(pdev); @@ -1733,7 +1735,7 @@ static void svc_i3c_restore_regs(struct svc_i3c_master *master) } } -static int __maybe_unused svc_i3c_runtime_suspend(struct device *dev) +int svc_i3c_master_runtime_suspend(struct device *dev) { struct svc_i3c_master *master = dev_get_drvdata(dev); @@ -1744,7 +1746,7 @@ static int __maybe_unused svc_i3c_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused svc_i3c_runtime_resume(struct device *dev) +int svc_i3c_master_runtime_resume(struct device *dev) { struct svc_i3c_master *master = dev_get_drvdata(dev); @@ -1756,30 +1758,6 @@ static int __maybe_unused svc_i3c_runtime_resume(struct device *dev) return 0; } -static const struct dev_pm_ops svc_i3c_pm_ops = { - SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) - SET_RUNTIME_PM_OPS(svc_i3c_runtime_suspend, - svc_i3c_runtime_resume, NULL) -}; - -static const struct of_device_id svc_i3c_master_of_match_tbl[] = { - { .compatible = "silvaco,i3c-master-v1"}, - { /* sentinel */ }, -}; -MODULE_DEVICE_TABLE(of, svc_i3c_master_of_match_tbl); - -static struct platform_driver svc_i3c_master = { - .probe = svc_i3c_master_probe, - .remove_new = svc_i3c_master_remove, - .driver = { - .name = "silvaco-i3c-master", - .of_match_table = svc_i3c_master_of_match_tbl, - .pm = &svc_i3c_pm_ops, - }, -}; -module_platform_driver(svc_i3c_master); - MODULE_AUTHOR("Conor Culhane "); MODULE_AUTHOR("Miquel Raynal "); MODULE_DESCRIPTION("Silvaco dual-role I3C master driver"); diff --git a/drivers/i3c/master/svc-i3c.h b/drivers/i3c/master/svc-i3c.h new file mode 100644 index 0000000000000..26a3fbcdb6524 --- /dev/null +++ b/drivers/i3c/master/svc-i3c.h @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 + +#ifndef SVC_I3C_H +#define SVC_I3C_H + +int svc_i3c_master_probe(struct platform_device *pdev); +void svc_i3c_master_remove(struct platform_device *pdev); +int svc_i3c_master_runtime_suspend(struct device *dev); +int svc_i3c_master_runtime_resume(struct device *dev); + +#endif + From patchwork Mon Jan 29 19:53:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Li X-Patchwork-Id: 767671 Received: from EUR01-HE1-obe.outbound.protection.outlook.com (mail-he1eur01on2044.outbound.protection.outlook.com [40.107.13.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 73149157050; Mon, 29 Jan 2024 19:54:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.13.44 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706558049; cv=fail; b=OcPHlhHPYXtZgDmx1Htvd/qUgCj+E9u7YKKDBPLLX53OnhcmYt3athkDmVJw8gJiuEqmRU1ujn/YVf88gI10qnteRLvdiXjwNeWzcSm+ZZWLUTYnHWpG5Jz7oIAB4nLElHO6wW/ZMCakYCXlPYNJ5UMPa1gYXbDs71jGBqZsPWE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706558049; c=relaxed/simple; bh=oL+H3dx45DTqLy3vG5zsOJMz4W/AofYYI/tOi5botrY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: Content-Type:MIME-Version; b=YvTMgGbBC74v6PnhFyBjX4YUDD6JWfaFP+yU6y3sOG0xVi2JA3x0NZdA+XTNG8EZi8yRulkghqTGKkp6I0sM8dqVX7iwc/j9kxSLVflrvdtY6ht+90V7RmJZs4bbus0bOqcWWFMCwV6QNPzJ1DFRcq6flwMiGXZ/3VqF1JqVoc0= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com; spf=pass smtp.mailfrom=nxp.com; dkim=pass (1024-bit key) header.d=nxp.com header.i=@nxp.com header.b=rmExsUmB; arc=fail smtp.client-ip=40.107.13.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nxp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=nxp.com header.i=@nxp.com header.b="rmExsUmB" ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=FraLzsdi1Ut0w4Bo/JDRf6nZ9BOeeMPYI5NJDUJ0sbyHylGpUbuFnMhgZJMqDng+vzmQLxzRFotYnozE83c1lTkIzoUwS1uaDU1mazaPpIJmfQN4yfX+RjFWDh0tz6Wt3nGOeY2DY/25aaYTvOAZ8B/fey15jU5oFVajRfb/Aa18pkgvQVChQRHYHHjbF4YPcMV5pZ4r1mfWhmDYjEPXteU76NM9mqobwWXQZLvvhG8lTqj8XBsJj+HFzl1UFcqwsS9qcj2fpA/0F4yPNXkl10/DfvrVXr+I8E17bQIwAsE/yiKYGbFwwxaPw97soAAcB0ZA1w1QOPIYZhElgok5BA== 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=bBfqdO5HHaFNgPy0YAFfb7aeA0l6qgQTYR8UHnlAJko=; b=Y4V/YfCNP5wMTbCqH4X8yg41HZxPTMiq/6/XGxfHp0Oem26LfaR3j66A/128TeTC30j+NVEgpeJZ0ugogM4hXgvX2bDSj5NWJrmPjodNh4vhIisIFUDa59ND6OvlKExA4bshXrP2RikPd4XxXjdM3nIE4o+rNEH4KbbHbMpgmU2ak3LOG3CAivOHT+zj2lZisZzn8kwjyTsQIjF7NkhjeHnfeqiGUKcsHkis4YR9CX10oZi6d83YkRsMySqzyIjbRFxpY1lt3FAxBMbJs8seB1sHHmJjYDdss9Vdx4Zy5iiD4Ntwao9Hy2yci4Aws7lXKrIbeQY5OQ49SCwTGpAw3A== 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=bBfqdO5HHaFNgPy0YAFfb7aeA0l6qgQTYR8UHnlAJko=; b=rmExsUmBBxmm/pmmdGwLEdghaD165OJxcC9ldJEvsZ8Lr6Ri5WtFS+PhaPEcLRsO01D17dIcOwmYdCGsx7ibGsQOKiyrD7GGOEQ1Z6D09C5hsCQP2xSJpOVEu0njSAj2KbopoMdl797Was38EF1grEQkgM2Hxf3Mbv6rw1HGbck= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from PAXPR04MB9642.eurprd04.prod.outlook.com (2603:10a6:102:240::14) by PAXPR04MB8128.eurprd04.prod.outlook.com (2603:10a6:102:1c8::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.32; Mon, 29 Jan 2024 19:54:04 +0000 Received: from PAXPR04MB9642.eurprd04.prod.outlook.com ([fe80::c8b4:5648:8948:e85c]) by PAXPR04MB9642.eurprd04.prod.outlook.com ([fe80::c8b4:5648:8948:e85c%3]) with mapi id 15.20.7228.029; Mon, 29 Jan 2024 19:54:04 +0000 From: Frank Li To: ilpo.jarvinen@linux.intel.com Cc: Frank.Li@nxp.com, alexandre.belloni@bootlin.com, conor.culhane@silvaco.com, devicetree@vger.kernel.org, gregkh@linuxfoundation.org, imx@lists.linux.dev, jirislaby@kernel.org, joe@perches.com, krzysztof.kozlowski+dt@linaro.org, krzysztof.kozlowski@linaro.org, linux-i3c@lists.infradead.org, linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, miquel.raynal@bootlin.com, robh@kernel.org, zbigniew.lukwinski@linux.intel.com Subject: [PATCH v5 6/8] i3c: target: func: add tty driver Date: Mon, 29 Jan 2024 14:53:19 -0500 Message-Id: <20240129195321.229867-7-Frank.Li@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240129195321.229867-1-Frank.Li@nxp.com> References: <20240129195321.229867-1-Frank.Li@nxp.com> X-ClientProxiedBy: BYAPR05CA0091.namprd05.prod.outlook.com (2603:10b6:a03:e0::32) To PAXPR04MB9642.eurprd04.prod.outlook.com (2603:10a6:102:240::14) Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PAXPR04MB9642:EE_|PAXPR04MB8128:EE_ X-MS-Office365-Filtering-Correlation-Id: 0f8cf867-2612-42b6-98e0-08dc21040c0c X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: FCQHHlawS4BRJEUaiCNclQNcF71O0PES8lQByLzbH7v/g7eLrPrGaQuM8anxw2lwlBgJmfKj2t0ZDyMyTrXlC1oKwUeAQvblkG7fT6st76qGXe2oGGFJYiqAIDIU+uL8tGycTGE/9WFIwpiuhjYl8s0HoVQ+1KmuXmm7wSaJ2ciOSndETgLV8GX9Oa7GdvKwF06fNQzlV/e0zPs6aU75RsSV2e2JXJtuGmHcgpfy5QW1fhlofHilw6Xt+GpuyV0TUzQE+LScf/nZuuP+dQqE0ecwuY8F4nwn6kwTJKFZlmPHe5HdmiAObjc6Gj4s+/NahECRSCopUeWTMAR0iqt/tbpJZ6puHHDExOSSnsUQYCf7JdXB0d0hBZuFcxpLmcb2PNEB6vg0yiSVuvIO2m/lGpNOxntpVCt0CPFwG9ReXGQUB9KdKUhu/h1WhkO1x0QfjfdvIv/Ue8lL8eS9cS5zqGu/MR9QRMvUBoFBSVNsQ7z/kZIMjEEVSwGhkRLRZHNoP2qgL7FkwLi5HC9/S3FP3yF793FkA+xLUfPXipHYBn8e8fD8NLbHk5ee0gwDXsqWWvlWfFPNvd2epeorELJkIM/C/gCWdBRTPFpIt6ws90NqmH7bp2gC0E5Ae3AaP3eJ X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PAXPR04MB9642.eurprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(376002)(39860400002)(136003)(366004)(346002)(396003)(230922051799003)(451199024)(1800799012)(186009)(64100799003)(1076003)(26005)(52116002)(83380400001)(6512007)(6666004)(6506007)(38100700002)(30864003)(66946007)(4326008)(5660300002)(8936002)(8676002)(7416002)(41300700001)(2616005)(316002)(478600001)(6916009)(2906002)(66476007)(6486002)(66556008)(86362001)(36756003)(38350700005); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: K9FZBvlN29bPqhFwR6dbFM9mfFB4yJ2x0OajV4KJs/v3t9TsUK8pegH/IONmGcCjsem7jPCcULBfGJkRd0VLYlE62y19pwz+nk+5XCpgiZkl/FjNN7EepIjgILl6u/YQvPBnyOGrHOqX/eD5bUXml/i1ogiudZHM6tZ5riKiT0v6reOHz+VWP4Xxj109fsGFDNPy1zvouEEZ40n+Fv1a1fTpwzHTEmy55c7FlNDlRKW2MDf1QwB3IXPC5U5ByeTIRpKerJm4+cIJksFa30HC+hpmu8mnPUMSpx2GbDqdNg5A2RNzyfAHcHnSJWRkNmZJ+KQZBSASpe+o16zwx49rj7BwGn1VQoDypb6LmzgewEjdcx2SqLnx8tSq6XF8tBBtj7utb7vGxQltRMZsqk9w92GVaRU8H/YfVbUI4kxiFWswZLcsXKJX/ZXPa/98Fn9dEpk0q7J+PRMVU/xJBhlDUYs+WA+A2CaN3PLlUl86KtGKyoWNOLh4ZgCtcY6rJZMdwi+MHlDYZnqdxpMa6DYhYmXoO4uOEGdsW4/woB50wi0YZD/2vjQQHQpencRtZ8jIaQMsrwCXTnVLCbfFjCWXsW1M6lzLDzMZQjmaHHPEyiWY9d/3GixvKUnv1f8BidCJxytEiUZZsiCJAbR5/HnXTNq/8LvKECar1XNtejCs3EBPd7iVhj6cmLu1gboSiLU/R09txMICTGqy37cgNtvO831q7j99aYUL4Rrejo31+DrUOTayJptUSJYq1d2zhmnKprE96JP3AhMUiG4My1uS96yMecqggZzC+k4W56n6MbIzuoKrcFe2reVDRmvg9Q8LFn2AdPEv5/ClDmB7Q9Gui8kQK8j3SoYk5uGlZuqG43/qZIFLXxoiJNfX9NUUxQZ1uw0AgCyc1yN8T6b009DWa80NW7EozwgsZVc4uNrJFUL+c2/yrV73TeOs6p59/x6ZM25TSdyCx/sV+A7Y+SZM31tjiau7tWjm4pneIPFQ2Iirrl7uNzC7LqV8awV9aaii9ADolkWa0vHcWryex8iYh5eVxJd+9Hj0H/3iBjKtiQDsSyJIV7HB+EidKiOUTBeQqNMO9hZ8d+YxxYIsR5fdmtf5fyVfdhjiuTKXDPMJT/c8T/nFPYpRLKaHIbbyh76fN2P1RCPO+hmuu5FPRyb5GOz6AKs/tzsWlEfBi8fG07C4oxkqtAFHaI6vKs6EqlWV9CdX6k90klYQVQLYIWbt9sRAyTmhW/dRy1X7o0EbJ8dDuFvNyEShAF5fcUBhjKLYpSxf6VqXWOL2tBlB3y+Z8HV0ICv3+WJWa7N7alUvgu6fj9fjUTLuqtTl7PAqC+0Frx1kF7klG4ae5/RO/WnzNMmq6xmp8B3L6c0WEmdQ2SrmF+Y0G4/5AHGvML1niZuqaBS1Mqm66VhlB8m5cgbS3VZk6Kfr9z5ko7hH9iG0jfgr/W+3c+z/BO/8e4onj879pjJU9sCfQLyQcvZVV2F5txp/F8hlJggCWqbh0cT81JE2jsq9pMFjg+UpkGTxRSgGcgGC8mjm+Yg0XTOXQdrRLF/etd1tkwiUUao+HfgOdGiJGvNH1NvA8PnPm7Em+UN/ X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 0f8cf867-2612-42b6-98e0-08dc21040c0c X-MS-Exchange-CrossTenant-AuthSource: PAXPR04MB9642.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Jan 2024 19:54:04.6777 (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: p+WN6TYFrG+5+rrytJBl1zXmITlg+8N5FutTb5wux3c7U1YA+EgHh2QSCgitOOfBmkncVyAwpMuO6acoLLiS6Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB8128 Add tty over I3C target function driver. Signed-off-by: Frank Li --- Notes: Change from v4 to v5 - remove void* - include bitfield.h - remove extra () - oneline for struct ttyi3c_port *sport drivers/i3c/Kconfig | 3 + drivers/i3c/Makefile | 1 + drivers/i3c/func/Kconfig | 9 + drivers/i3c/func/Makefile | 3 + drivers/i3c/func/tty.c | 474 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 490 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 d59a7eb83d13a..fca808cda87b3 100644 --- a/drivers/i3c/Kconfig +++ b/drivers/i3c/Kconfig @@ -48,3 +48,6 @@ config I3C_TARGET_CONFIGFS the target function and used to bind the function with a target controller. +if I3C_TARGET +source "drivers/i3c/func/Kconfig" +endif # I3C_TARGET diff --git a/drivers/i3c/Makefile b/drivers/i3c/Makefile index c275aeae8970c..11f026d6876fe 100644 --- a/drivers/i3c/Makefile +++ b/drivers/i3c/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_I3C) += i3c.o obj-$(CONFIG_I3C_TARGET) += target.o obj-$(CONFIG_I3C_TARGET_CONFIGFS) += i3c-cfs.o obj-$(CONFIG_I3C) += master/ +obj-$(CONFIG_I3C_TARGET) += func/ diff --git a/drivers/i3c/func/Kconfig b/drivers/i3c/func/Kconfig new file mode 100644 index 0000000000000..7115129eb7d5a --- /dev/null +++ b/drivers/i3c/func/Kconfig @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 + +config I3C_TARGET_FUNC_TTY + tristate "I3C target tty driver" + depends on I3C_TARGET + help + I3C Target TTY Function Driver. + + General TTY over I3C target controller function drivers. diff --git a/drivers/i3c/func/Makefile b/drivers/i3c/func/Makefile new file mode 100644 index 0000000000000..16b3b9301496b --- /dev/null +++ b/drivers/i3c/func/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_I3C_TARGET_FUNC_TTY) += tty.o diff --git a/drivers/i3c/func/tty.c b/drivers/i3c/func/tty.c new file mode 100644 index 0000000000000..50673bfb6a003 --- /dev/null +++ b/drivers/i3c/func/tty.c @@ -0,0 +1,474 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2023 NXP + * Author: Frank Li + */ + +#include +#include +#include +#include +#include +#include + +static DEFINE_IDR(i3c_tty_minors); + +static struct tty_driver *i3c_tty_driver; + +#define I3C_TTY_MINORS 8 + +#define I3C_TX_NOEMPTY BIT(0) +#define I3C_TTY_TRANS_SIZE 16 +#define I3C_TTY_IBI_TX BIT(0) + +struct ttyi3c_port { + struct tty_port port; + int minor; + struct i3c_target_func *i3cdev; + struct completion txcomplete; + spinlock_t xlock; + void *buffer; + struct work_struct work; + u16 status; + struct i3c_request *req; +}; + +static void i3c_target_tty_rx_complete(struct i3c_request *req) +{ + struct ttyi3c_port *port = req->context; + + if (req->status == I3C_REQUEST_CANCEL) { + i3c_target_ctrl_free_request(req); + return; + } + + tty_insert_flip_string(&port->port, req->buf, req->actual); + tty_flip_buffer_push(&port->port); + + req->actual = 0; + req->status = 0; + i3c_target_ctrl_queue(req, GFP_KERNEL); +} + +static void i3c_target_tty_tx_complete(struct i3c_request *req) +{ + struct ttyi3c_port *sport = req->context; + unsigned long flags; + + if (req->status == I3C_REQUEST_CANCEL) { + i3c_target_ctrl_free_request(req); + return; + } + + spin_lock_irqsave(&sport->xlock, flags); + kfifo_dma_out_finish(&sport->port.xmit_fifo, req->actual); + sport->req = NULL; + + if (kfifo_is_empty(&sport->port.xmit_fifo)) + complete(&sport->txcomplete); + else + queue_work(system_unbound_wq, &sport->work); + + if (kfifo_len(&sport->port.xmit_fifo) < WAKEUP_CHARS) + tty_port_tty_wakeup(&sport->port); + spin_unlock_irqrestore(&sport->xlock, flags); + + i3c_target_ctrl_free_request(req); +} + +static void i3c_target_tty_i3c_work(struct work_struct *work) +{ + struct ttyi3c_port *sport = container_of(work, struct ttyi3c_port, work); + struct i3c_request *req = sport->req; + struct scatterlist sg[1]; + unsigned int nents; + u8 ibi; + + if (kfifo_is_empty(&sport->port.xmit_fifo)) + return; + + if (!req) { + req = i3c_target_ctrl_alloc_request(sport->i3cdev->ctrl, GFP_KERNEL); + if (!req) + return; + + sg_init_table(sg, ARRAY_SIZE(sg)); + nents = kfifo_dma_out_prepare(&sport->port.xmit_fifo, sg, ARRAY_SIZE(sg), + UART_XMIT_SIZE); + if (!nents) + goto err; + + req->length = sg->length; + req->buf = sg_virt(sg); + + req->complete = i3c_target_tty_tx_complete; + req->context = sport; + req->tx = true; + + if (i3c_target_ctrl_queue(req, GFP_KERNEL)) + goto err; + + sport->req = req; + } + + ibi = I3C_TTY_IBI_TX; + i3c_target_ctrl_raise_ibi(sport->i3cdev->ctrl, &ibi, 1); + + return; + +err: + i3c_target_ctrl_free_request(req); +} + +static int i3c_port_activate(struct tty_port *port, struct tty_struct *tty) +{ + struct ttyi3c_port *sport = container_of(port, struct ttyi3c_port, port); + const struct i3c_target_ctrl_features *feature; + struct i3c_target_func *func = sport->i3cdev; + struct i3c_request *req; + int rxfifo_size; + int offset = 0; + int ret; + + feature = i3c_target_ctrl_get_features(func->ctrl); + if (!feature) + return -EINVAL; + + ret = tty_port_alloc_xmit_buf(port); + if (ret) + return ret; + + sport->buffer = (void *)get_zeroed_page(GFP_KERNEL); + if (!sport->buffer) + goto err_alloc_rx_buf; + + rxfifo_size = feature->rx_fifo_sz; + + if (!rxfifo_size) + rxfifo_size = I3C_TTY_TRANS_SIZE; + + do { + req = i3c_target_ctrl_alloc_request(func->ctrl, GFP_KERNEL); + if (!req) + goto err_alloc_req; + + req->buf = sport->buffer + offset; + req->length = rxfifo_size; + req->context = sport; + req->complete = i3c_target_tty_rx_complete; + offset += rxfifo_size; + + if (i3c_target_ctrl_queue(req, GFP_KERNEL)) + goto err_alloc_req; + } while (req && offset + rxfifo_size < UART_XMIT_SIZE); + + reinit_completion(&sport->txcomplete); + + return 0; + +err_alloc_req: + i3c_target_ctrl_cancel_all_reqs(func->ctrl, false); + free_page((unsigned long)sport->buffer); +err_alloc_rx_buf: + tty_port_free_xmit_buf(port); + return -ENOMEM; +} + +static void i3c_port_shutdown(struct tty_port *port) +{ + struct ttyi3c_port *sport = container_of(port, struct ttyi3c_port, port); + + cancel_work_sync(&sport->work); + + i3c_target_ctrl_cancel_all_reqs(sport->i3cdev->ctrl, true); + i3c_target_ctrl_cancel_all_reqs(sport->i3cdev->ctrl, false); + + i3c_target_ctrl_fifo_flush(sport->i3cdev->ctrl, true); + i3c_target_ctrl_fifo_flush(sport->i3cdev->ctrl, false); + + tty_port_free_xmit_buf(port); + free_page((unsigned long)sport->buffer); +} + +static void i3c_port_destruct(struct tty_port *port) +{ + struct ttyi3c_port *sport = container_of(port, struct ttyi3c_port, port); + + idr_remove(&i3c_tty_minors, sport->minor); +} + +static const struct tty_port_operations i3c_port_ops = { + .shutdown = i3c_port_shutdown, + .activate = i3c_port_activate, + .destruct = i3c_port_destruct, +}; + +static int i3c_target_tty_bind(struct i3c_target_func *func) +{ + struct ttyi3c_port *sport; + struct device *tty_dev; + int minor; + int ret; + + sport = dev_get_drvdata(&func->dev); + + if (i3c_target_ctrl_set_config(func->ctrl, func)) { + dev_err(&func->dev, "failed to set i3c config\n"); + return -EINVAL; + } + + spin_lock_init(&sport->xlock); + init_completion(&sport->txcomplete); + + ret = minor = idr_alloc(&i3c_tty_minors, sport, 0, I3C_TTY_MINORS, GFP_KERNEL); + + if (minor < 0) + goto err_idr_alloc; + + tty_port_init(&sport->port); + sport->port.ops = &i3c_port_ops; + + tty_dev = tty_port_register_device(&sport->port, i3c_tty_driver, minor, + &func->dev); + if (IS_ERR(tty_dev)) { + ret = PTR_ERR(tty_dev); + goto err_register_port; + } + + sport->minor = minor; + ret = i3c_target_ctrl_enable(func->ctrl); + if (ret) + goto err_ctrl_enable; + + return 0; + +err_ctrl_enable: + tty_port_unregister_device(&sport->port, i3c_tty_driver, sport->minor); +err_register_port: + idr_remove(&i3c_tty_minors, sport->minor); +err_idr_alloc: + i3c_target_ctrl_cancel_all_reqs(func->ctrl, false); + dev_err(&func->dev, "bind failure\n"); + + return ret; +} + +static void i3c_target_tty_unbind(struct i3c_target_func *func) +{ + struct ttyi3c_port *sport; + + sport = dev_get_drvdata(&func->dev); + + cancel_work_sync(&sport->work); + + i3c_target_ctrl_disable(func->ctrl); + i3c_target_ctrl_cancel_all_reqs(func->ctrl, 0); + i3c_target_ctrl_cancel_all_reqs(func->ctrl, 1); + + tty_port_unregister_device(&sport->port, i3c_tty_driver, sport->minor); + + free_page((unsigned long)sport->buffer); +} + +static struct i3c_target_func_ops i3c_func_ops = { + .bind = i3c_target_tty_bind, + .unbind = i3c_target_tty_unbind, +}; + +static int i3c_tty_probe(struct i3c_target_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; + dev_set_drvdata(&func->dev, port); + + INIT_WORK(&port->work, i3c_target_tty_i3c_work); + + return 0; +} + +static ssize_t i3c_write(struct tty_struct *tty, const unsigned char *buf, size_t count) +{ + struct ttyi3c_port *sport = tty->driver_data; + unsigned long flags; + bool is_empty; + int ret = 0; + + spin_lock_irqsave(&sport->xlock, flags); + ret = kfifo_in(&sport->port.xmit_fifo, buf, count); + is_empty = kfifo_is_empty(&sport->port.xmit_fifo); + i3c_target_ctrl_set_status_format1(sport->i3cdev->ctrl, sport->status | I3C_TX_NOEMPTY); + spin_unlock_irqrestore(&sport->xlock, flags); + + if (!is_empty) + queue_work(system_unbound_wq, &sport->work); + + return ret; +} + +static int i3c_put_char(struct tty_struct *tty, unsigned char ch) +{ + struct ttyi3c_port *sport = tty->driver_data; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&sport->xlock, flags); + ret = kfifo_put(&sport->port.xmit_fifo, ch); + spin_unlock_irqrestore(&sport->xlock, flags); + + return ret; +} + +static void i3c_flush_chars(struct tty_struct *tty) +{ + struct ttyi3c_port *sport = tty->driver_data; + unsigned long flags; + + spin_lock_irqsave(&sport->xlock, flags); + if (!kfifo_is_empty(&sport->port.xmit_fifo)) + queue_work(system_unbound_wq, &sport->work); + spin_unlock_irqrestore(&sport->xlock, flags); +} + +static unsigned int i3c_write_room(struct tty_struct *tty) +{ + struct ttyi3c_port *sport = tty->driver_data; + + return kfifo_avail(&sport->port.xmit_fifo); +} + +static void i3c_throttle(struct tty_struct *tty) +{ + struct ttyi3c_port *sport = tty->driver_data; + + i3c_target_ctrl_cancel_all_reqs(sport->i3cdev->ctrl, false); +} + +static void i3c_unthrottle(struct tty_struct *tty) +{ + struct ttyi3c_port *sport = tty->driver_data; + + i3c_port_activate(&sport->port, tty); +} + +static int i3c_open(struct tty_struct *tty, struct file *filp) +{ + struct ttyi3c_port *sport = container_of(tty->port, struct ttyi3c_port, port); + int ret; + + tty->driver_data = sport; + + if (!i3c_target_ctrl_get_addr(sport->i3cdev->ctrl)) { + dev_dbg(&sport->i3cdev->dev, "No target addr assigned, try hotjoin"); + ret = i3c_target_ctrl_hotjoin(sport->i3cdev->ctrl); + if (ret) { + dev_err(&sport->i3cdev->dev, "Hotjoin failure, check connection"); + return ret; + } + } + + return tty_port_open(&sport->port, tty, filp); +} + +static void i3c_close(struct tty_struct *tty, struct file *filp) +{ + tty_port_close(tty->port, tty, filp); +} + +static void i3c_wait_until_sent(struct tty_struct *tty, int timeout) +{ + struct ttyi3c_port *sport = tty->driver_data; + int val; + int ret; + u8 ibi = I3C_TTY_IBI_TX; + int retry = 100; + + if (!kfifo_is_empty(&sport->port.xmit_fifo)) { + do { + ret = wait_for_completion_timeout(&sport->txcomplete, timeout / 100); + if (ret) + break; + i3c_target_ctrl_raise_ibi(sport->i3cdev->ctrl, &ibi, 1); + } while (retry--); + + reinit_completion(&sport->txcomplete); + } + + read_poll_timeout(i3c_target_ctrl_fifo_status, val, !val, 100, timeout, false, + sport->i3cdev->ctrl, true); + + i3c_target_ctrl_set_status_format1(sport->i3cdev->ctrl, sport->status & ~I3C_TX_NOEMPTY); +} + +static const struct tty_operations i3c_tty_ops = { + .open = i3c_open, + .close = i3c_close, + .write = i3c_write, + .put_char = i3c_put_char, + .flush_chars = i3c_flush_chars, + .write_room = i3c_write_room, + .throttle = i3c_throttle, + .unthrottle = i3c_unthrottle, + .wait_until_sent = i3c_wait_until_sent, +}; + +DECLARE_I3C_TARGET_FUNC(tty, i3c_tty_probe, NULL, &i3c_func_ops); + +static int __init i3c_tty_init(void) +{ + int ret; + + i3c_tty_driver = tty_alloc_driver( + I3C_TTY_MINORS, TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); + + if (IS_ERR(i3c_tty_driver)) + return PTR_ERR(i3c_tty_driver); + + i3c_tty_driver->driver_name = "ttySI3C", i3c_tty_driver->name = "ttySI3C", + i3c_tty_driver->minor_start = 0, + i3c_tty_driver->type = TTY_DRIVER_TYPE_SERIAL, + i3c_tty_driver->subtype = SERIAL_TYPE_NORMAL, + i3c_tty_driver->init_termios = tty_std_termios; + i3c_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | + CLOCAL; + i3c_tty_driver->init_termios.c_lflag = 0; + + tty_set_operations(i3c_tty_driver, &i3c_tty_ops); + + ret = tty_register_driver(i3c_tty_driver); + if (ret) + goto err_register_tty_driver; + + ret = i3c_target_func_register_driver(&ttyi3c_func); + if (ret) + goto err_register_i3c_driver; + + return 0; + +err_register_i3c_driver: + tty_unregister_driver(i3c_tty_driver); + +err_register_tty_driver: + tty_driver_kref_put(i3c_tty_driver); + + return ret; +} + +static void __exit i3c_tty_exit(void) +{ + i3c_target_func_unregister_driver(&ttyi3c_func); + tty_unregister_driver(i3c_tty_driver); + tty_driver_kref_put(i3c_tty_driver); + idr_destroy(&i3c_tty_minors); +} + +module_init(i3c_tty_init); +module_exit(i3c_tty_exit); + +MODULE_LICENSE("GPL"); + From patchwork Mon Jan 29 19:53:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Li X-Patchwork-Id: 767670 Received: from EUR01-HE1-obe.outbound.protection.outlook.com (mail-he1eur01on2058.outbound.protection.outlook.com [40.107.13.58]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 289F215A4AB; Mon, 29 Jan 2024 19:54:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.13.58 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706558057; cv=fail; b=FOaETzMLTvMaKf1opXAEwrCC290qSn8w6cSIeif1fVRWdd3LjeiSGNbSSRhJI8w17f9Rf826B9Lc1YqijWflpzZABg5Cx2OxVZ5OM5k5n37jroq3snmXwCu3lWvjfSk658R+MPCXQZQ36+whn0W7DXuB7zpaJiXko1UGxf35nro= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706558057; c=relaxed/simple; bh=OJx1NMfFMiH01ARiZQxTgg67iXYJlPTgevmQUiPaJUg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: Content-Type:MIME-Version; b=te1iVD+4B2z4XJ2i69blHWNt9Z29RMnHYEgl526Hcw6MnW6F0iZpcEL+2uhuQ0juV89SDWb/1LQtpEgzW2g5CGC/7FZcM77EO3zE6r2trkbsTH0/FbMiXMC3Nv8iUhDqqK75RlDj9CJoKWVYtWHQo65BEylnF15nE7cuBbsYREY= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com; spf=pass smtp.mailfrom=nxp.com; dkim=pass (1024-bit key) header.d=nxp.com header.i=@nxp.com header.b=Rj/Qvh0P; arc=fail smtp.client-ip=40.107.13.58 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nxp.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nxp.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=nxp.com header.i=@nxp.com header.b="Rj/Qvh0P" ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=kzuknjQAjfecTBXE44RaRG84Kr0VI6IA011lNRrFx6+4ITfihe9z8TLOUKBgWSQRtoXeVIsZU8MjCLgsQkVsALRVYteEkw1kYI8lHeQVXuMSSyu/6ybbXopxHfj5ygbeuFprJSVa8dFunsz288qOUlJUOwAgjaJDyAVAweCkJexwZHGF2b0CMrziGdTpWnll+ShFIoWIj9tEZvJ39bC+DuO7wWx2YavxsjJ+4d0jgZ7/Fa9XEXGlaYqGHcF2HZuhO+SJQvbYQOjcivi45QhHJ1otmaDjPdU8RiqBuUHOgFZkdCJDdhtXvWXOXeSQoRLqvVfPd9dG1uPyZLpvIruJDw== 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=r2ZuRn8t6n53DIhVuueFkYHGrzzkYUywxYot6m9s1co=; b=EndsqVvC1rSh0vdrjIiYl9QD3XVVOKgM3E5TNmH3XUo1qG4STjHyt/7btjYWVVYDtOwJGOTnJHWj/PuzDhh0/LDcwjwWO57p848ASEepC2e8f818o/HzuUQ9YqeIwB7p0eLhJC0IBIZWaXQmS2R64qSyOvgWEzRsGiHICw0etFO4C7ez9XbLFVOdouqjRQXKAWPPZOu7jtKV8RIzyCNhVKOzmtqugWUn6RhdH152eyF2P5a0nBptMUUhB4SgYH1UyN7bmweQ/qMidgjgkkrSF0XewW2eP5oonVT6mC2f1lhfQLgpipBP+suqwJVCTKBz9+Ds1Z0YFlE+JoGayUQgtg== 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=r2ZuRn8t6n53DIhVuueFkYHGrzzkYUywxYot6m9s1co=; b=Rj/Qvh0PBea9XIEqSUkFhNCA2D2JEP3vuHdB7v1cNmfGTYwq7G3lQfbGEZeJi18yj6LCXlCmK4hoa16FItv3sqrjom3uXPriPw6OFJbinYnkiM7aes+57Z6cj+4+Y1CMDV+H2XCa1UesfK5zhElbCczOnZk54XFibF6vgPp05CM= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nxp.com; Received: from PAXPR04MB9642.eurprd04.prod.outlook.com (2603:10a6:102:240::14) by PAXPR04MB8128.eurprd04.prod.outlook.com (2603:10a6:102:1c8::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.32; Mon, 29 Jan 2024 19:54:13 +0000 Received: from PAXPR04MB9642.eurprd04.prod.outlook.com ([fe80::c8b4:5648:8948:e85c]) by PAXPR04MB9642.eurprd04.prod.outlook.com ([fe80::c8b4:5648:8948:e85c%3]) with mapi id 15.20.7228.029; Mon, 29 Jan 2024 19:54:13 +0000 From: Frank Li To: ilpo.jarvinen@linux.intel.com Cc: Frank.Li@nxp.com, alexandre.belloni@bootlin.com, conor.culhane@silvaco.com, devicetree@vger.kernel.org, gregkh@linuxfoundation.org, imx@lists.linux.dev, jirislaby@kernel.org, joe@perches.com, krzysztof.kozlowski+dt@linaro.org, krzysztof.kozlowski@linaro.org, linux-i3c@lists.infradead.org, linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, miquel.raynal@bootlin.com, robh@kernel.org, zbigniew.lukwinski@linux.intel.com Subject: [PATCH v5 8/8] tty: i3c: add TTY over I3C master support Date: Mon, 29 Jan 2024 14:53:21 -0500 Message-Id: <20240129195321.229867-9-Frank.Li@nxp.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240129195321.229867-1-Frank.Li@nxp.com> References: <20240129195321.229867-1-Frank.Li@nxp.com> X-ClientProxiedBy: BYAPR05CA0091.namprd05.prod.outlook.com (2603:10b6:a03:e0::32) To PAXPR04MB9642.eurprd04.prod.outlook.com (2603:10a6:102:240::14) Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PAXPR04MB9642:EE_|PAXPR04MB8128:EE_ X-MS-Office365-Filtering-Correlation-Id: 71fa63c3-3f15-4259-0c3b-08dc21041123 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: dPJxDN+zsI99Gb/0BHUr+yoKJXEzOPAeT2qHH/0rDhvRLRmcZV7GuvuhtNI+subUoW36Rt/fasYEszHHhAEn3PSxXsv8HVwcDzvBh1jrF+sIQWCaPNM074V1y80GeBi9VnK6sVCUXtnZk9h1MCs70OnZ8ncLKiKVMH9OKylac9fBtlDJm+HT7M78Q9kHpw+SfABEHcgeGr6fpwDq9LZrnttLzKr0xp4HW2kZi7SlQJK1ZNfMJm6h9VBlH5cGRTptET1l3tt/EtD505W772hrBqgTMnx8ByHMiWb5bzLwusLCGbZtT534J3htH3PQB70FF22YJ4LqGSQCvUGd9pDYxZVST3fh+aCjWHgS1H7sxAL/oB5IzIiDEz2mNLn2JvGPTcFfBk226XLcdTU7NRFz3kZctNNjUVtQIYm7SY6u4lfUuHyRm+Y0gwEKq5RYX4MCRDqGYnpmkmYbF/upETVpD1gyWCm8My2PFFfu8W7qjB5Xe+c3ZLE+BCUEd0zJJQGkuW7f/ZLwVEjbfG7ABxms1WtH5nTBt9YsJEDsXBthks5ykHcc8Y8Tk2fzLiSTERO0KmhFOeDcpGuam9TfO0sbkJOZFpGHvHIw2CWuP2K2cnPE3VoVQUhqltmUBIYoUeoc X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PAXPR04MB9642.eurprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(376002)(39860400002)(136003)(366004)(346002)(396003)(230922051799003)(451199024)(1800799012)(186009)(64100799003)(1076003)(26005)(52116002)(83380400001)(6512007)(6666004)(6506007)(38100700002)(30864003)(66946007)(4326008)(5660300002)(8936002)(8676002)(7416002)(41300700001)(2616005)(316002)(478600001)(6916009)(2906002)(66476007)(6486002)(66556008)(86362001)(36756003)(38350700005); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: w0Vnwn+sPDfJTyE1Zeq3nuYNgpeQYOg9GmWW5pXI4IAVG76NBl9nlekPxYw2G2/pcf4oqLxgNpZGjXITaBqyypctpQ7oVRIfK33JzBRrTTZupExO+A31KATulQ8tYYTB3uIjVUawUmCUPtQzSbbyt/e8URPk5BV0atV9ef5IJWYC+yWXbZCavjAUQs9K1lBZFnmcFfwJE0+jn4GG0fdUBkGxiynFgKPOSH1PlwFfPKnaEn9YGCaVIBwctm83qlOSbUpd1kVspEkHEVoaKBaGvqPuZcbh+Rz8bQzvoBH2mLS786guETd8McePAj8lsfQ35Iab2KmHfVQ9Y+lwiEpaZkEd6IeUhAUonj49P9yQhAqh08N/SiQnyEHragd7Ds1GTqkKHi6XAjPRWjjjS9V+USzt8yh8QAANTvN35icqNlh3K6fWi/o5YqnUbALObASo1ovqeBZc3NRTbjJjxEhdZcDHsnc9fZ2jjDboeNuj9zzB5SKl5u0MSjCrSpcJ5eTR2R6u1/kxaosqjYQSF57LzxS2lGVwyQvIgxYqHyo5SErxtBgXvwyo6C55NrZlNlpgOI3xvelBmLCT+iaAZ7ilHtcB7vpKBhqY7uPmXQrvy+dR4CqAxZAPB8/b1wRpbq5BMypYWS6HtGUlOSdLAgiMcaBUgk777RjYgKpULmgWYkkBQK6LjRyANGzKB6Jfn+GpxeGiLA74/Ferj+VA2geTmyQaZ+S9xluPSbzL+CydDQlOocH5jX9AACh9QU2ATDIdCRLqHua3tOEwsWTqJnDcCIKE9nWRbByG3ksmWKDh17UGPMz6SgIEh01FdUMgG9zXtJTEcNQf4gmosZKiKksyIyYRg0AjfoxZMMV8rCu16m2ocsYrbS0eSuTYxw3o0j+jS+PflplEEWjTUkuqCov9xzkMlhA4+fcjTXlRWE6mwA8DETHRTS4JFprFrelPdrf6BIAYWbimGdjuJM97cNqgM+dL3kKic70B+1zLu0Izg6umqkuNd0rmYXINdqWVvCJcfw4l9M8wk494swwiV2esaQYdIUfkF6TW2wKnV6ZaVn6n5qRDmfvfmaBxire/ZxYRvnFAnGIJGQpdFZf8IkBRdKn2TfPrC0VAFfNG0HPg9Osv8EOj+S0u/MpW2LRvpZc/eK0AXVPJQTIGet+cFpxSZI2b2lDrkLjQZRBov4YvEGzCXPe6jkN4OG6M8JvTA9FRHtdtPD0/7e+wnbitTomlT+YhSoGGINQSWWVqternHUO+l8QIYwe58YxY4lgWnjK1jNgXpDjaBYWoDVU4rmSS7+IokCv62mjD1/lHb3GJXg52pJDhEEm15KrYjj3WtOj9BNsTXcrfNhW37K7T9j8jPEwcn5OJOakvsMrb1BhuIhfRD4AVjtO9FtgnMgvV1mny6E/FSDcIecuqi0yHKcvHchyCimouyKMXjiR+KI0sYK52zpu4AF+P188MQEPAWGIPwf3YyHujtX+Wx4Ics8ShBCAU1MwGiwGmtNoE0xIqNm1fayPnDD70bn5Ye6DdOrdIPgYP9EG0vv7ugF208p27DtZHG8HUd8PH46cOnNHr0eCy+FS4XUWz3tTVnYNxISSp X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 71fa63c3-3f15-4259-0c3b-08dc21041123 X-MS-Exchange-CrossTenant-AuthSource: PAXPR04MB9642.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Jan 2024 19:54:13.3163 (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: tLnZ1wqqswgW+29vCTJzRagFFV2j2sjnuKf+C4KKc1gZZEk3fD4zAS4wkYLiPPT2pdg4uLXXE+iz26IsDlO4Yw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAXPR04MB8128 In typical embedded Linux systems, UART consoles require at least two pins, TX and RX. In scenarios where I2C/I3C devices like sensors or PMICs are present, we can save these two pins by using this driver. Pins is crucial resources, especially in small chip packages. This introduces support for using the I3C bus to transfer console tty data, effectively replacing the need for dedicated UART pins. This not only conserves valuable pin resources but also facilitates testing of I3C's advanced features, including early termination, in-band interrupt (IBI) support, and the creation of more complex data patterns. Additionally, it aids in identifying and addressing issues within the I3C controller driver. Signed-off-by: Frank Li --- Notes: Notes: Version number use i3c target patches. Change from v4 to v5 - add missed header file - add define for BIT(0) - oneline for struct ttyi3c_port *sport Change from v3 to v4 - add static at i3c_remove() Change v2 - using system_unbound_wq working queue - fixed accoring to Jiri Slaby's comments Change before send with i3c target support Change from v4 to v5 - send in i3c improvememtn patches. Change from v2 to v4 - none Change from v1 to v2 - update commit message. - using goto for err handle - using one working queue for all tty-i3c device - fixed typo found by js - update kconfig help - using kfifo Still below items not be fixed (according to Jiri Slaby's comments) - rxwork thread: need trigger from two position. - common thread queue: need some suggestion Notes: Version number use i3c target patches. Change from v3 to v4 - add static at i3c_remove() Change v2 - using system_unbound_wq working queue - fixed accoring to Jiri Slaby's comments Change before send with i3c target support Change from v4 to v5 - send in i3c improvememtn patches. Change from v2 to v4 - none Change from v1 to v2 - update commit message. - using goto for err handle - using one working queue for all tty-i3c device - fixed typo found by js - update kconfig help - using kfifo Still below items not be fixed (according to Jiri Slaby's comments) - rxwork thread: need trigger from two position. - common thread queue: need some suggestion drivers/tty/Kconfig | 13 ++ drivers/tty/Makefile | 1 + drivers/tty/i3c_tty.c | 427 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 441 insertions(+) create mode 100644 drivers/tty/i3c_tty.c diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index 5646dc6242cd9..9ab4cd480e9f8 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig @@ -412,6 +412,19 @@ config RPMSG_TTY To compile this driver as a module, choose M here: the module will be called rpmsg_tty. +config I3C_TTY + tristate "TTY over I3C" + depends on I3C + help + Select this option to use TTY over I3C master controller. + + This makes it possible for user-space programs to send and receive + data as a standard tty protocol. I3C provide relatively higher data + transfer rate and less pin numbers, SDA/SCL are shared with other + devices. + + If unsure, say N + endif # TTY source "drivers/tty/serdev/Kconfig" diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index 07aca5184a55d..f329f9c7d308a 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile @@ -27,5 +27,6 @@ obj-$(CONFIG_GOLDFISH_TTY) += goldfish.o obj-$(CONFIG_MIPS_EJTAG_FDC_TTY) += mips_ejtag_fdc.o obj-$(CONFIG_VCC) += vcc.o obj-$(CONFIG_RPMSG_TTY) += rpmsg_tty.o +obj-$(CONFIG_I3C_TTY) += i3c_tty.o obj-y += ipwireless/ diff --git a/drivers/tty/i3c_tty.c b/drivers/tty/i3c_tty.c new file mode 100644 index 0000000000000..e6c9ad2f251fe --- /dev/null +++ b/drivers/tty/i3c_tty.c @@ -0,0 +1,427 @@ +// 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 + +static DEFINE_IDR(i3c_tty_minors); +static DEFINE_MUTEX(i3c_tty_minors_lock); + +static struct tty_driver *i3c_tty_driver; + +#define I3C_TTY_MINORS 8 +#define I3C_TTY_TRANS_SIZE 16 +#define I3C_TTY_RX_STOP 0 +#define I3C_TTY_RETRY 20 +#define I3C_TTY_YIELD_US 100 +#define I3C_TTY_TARGET_RX_READY BIT(0) + +struct ttyi3c_port { + struct tty_port port; + int minor; + spinlock_t xlock; /* protect xmit */ + u8 tx_buff[I3C_TTY_TRANS_SIZE]; + u8 rx_buff[I3C_TTY_TRANS_SIZE]; + struct i3c_device *i3cdev; + struct work_struct txwork; + struct work_struct rxwork; + struct completion txcomplete; + unsigned long status; + u32 buf_overrun; +}; + +static const struct i3c_device_id i3c_ids[] = { + I3C_DEVICE(0x011B, 0x1000, NULL), + { /* sentinel */ }, +}; + +static int i3c_port_activate(struct tty_port *port, struct tty_struct *tty) +{ + struct ttyi3c_port *sport = container_of(port, struct ttyi3c_port, port); + int ret; + + ret = tty_port_alloc_xmit_buf(port); + if (ret < 0) + return ret; + + sport->status = 0; + + ret = i3c_device_enable_ibi(sport->i3cdev); + if (ret) { + tty_port_free_xmit_buf(port); + return ret; + } + + return 0; +} + +static void i3c_port_shutdown(struct tty_port *port) +{ + struct ttyi3c_port *sport = container_of(port, struct ttyi3c_port, port); + + i3c_device_disable_ibi(sport->i3cdev); + tty_port_free_xmit_buf(port); +} + +static void i3c_port_destruct(struct tty_port *port) +{ + struct ttyi3c_port *sport = container_of(port, struct ttyi3c_port, port); + + mutex_lock(&i3c_tty_minors_lock); + idr_remove(&i3c_tty_minors, sport->minor); + mutex_unlock(&i3c_tty_minors_lock); +} + +static const struct tty_port_operations i3c_port_ops = { + .shutdown = i3c_port_shutdown, + .activate = i3c_port_activate, + .destruct = i3c_port_destruct, +}; + +static ssize_t i3c_write(struct tty_struct *tty, const unsigned char *buf, size_t count) +{ + struct ttyi3c_port *sport = tty->driver_data; + unsigned long flags; + bool is_empty; + int ret; + + spin_lock_irqsave(&sport->xlock, flags); + ret = kfifo_in(&sport->port.xmit_fifo, buf, count); + is_empty = kfifo_is_empty(&sport->port.xmit_fifo); + spin_unlock_irqrestore(&sport->xlock, flags); + + if (!is_empty) + queue_work(system_unbound_wq, &sport->txwork); + + return ret; +} + +static int i3c_put_char(struct tty_struct *tty, unsigned char ch) +{ + struct ttyi3c_port *sport = tty->driver_data; + unsigned long flags; + int ret; + + spin_lock_irqsave(&sport->xlock, flags); + ret = kfifo_put(&sport->port.xmit_fifo, ch); + spin_unlock_irqrestore(&sport->xlock, flags); + + return ret; +} + +static void i3c_flush_chars(struct tty_struct *tty) +{ + struct ttyi3c_port *sport = tty->driver_data; + + queue_work(system_unbound_wq, &sport->txwork); +} + +static unsigned int i3c_write_room(struct tty_struct *tty) +{ + struct ttyi3c_port *sport = tty->driver_data; + + return kfifo_avail(&sport->port.xmit_fifo); +} + +static void i3c_throttle(struct tty_struct *tty) +{ + struct ttyi3c_port *sport = tty->driver_data; + + clear_bit(I3C_TTY_RX_STOP, &sport->status); +} + +static void i3c_unthrottle(struct tty_struct *tty) +{ + struct ttyi3c_port *sport = tty->driver_data; + + set_bit(I3C_TTY_RX_STOP, &sport->status); + + queue_work(system_unbound_wq, &sport->rxwork); +} + +static int i3c_open(struct tty_struct *tty, struct file *filp) +{ + struct ttyi3c_port *sport = container_of(tty->port, struct ttyi3c_port, port); + + tty->driver_data = sport; + + return tty_port_open(&sport->port, tty, filp); +} + +static void i3c_close(struct tty_struct *tty, struct file *filp) +{ + tty_port_close(tty->port, tty, filp); +} + +static const struct tty_operations i3c_tty_ops = { + .open = i3c_open, + .close = i3c_close, + .write = i3c_write, + .put_char = i3c_put_char, + .flush_chars = i3c_flush_chars, + .write_room = i3c_write_room, + .throttle = i3c_throttle, + .unthrottle = i3c_unthrottle, +}; + +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); + + /* i3c_unthrottle also queue the work to fetch pending data in target side */ + queue_work(system_unbound_wq, &sport->rxwork); +} + +static void tty_i3c_rxwork(struct work_struct *work) +{ + struct ttyi3c_port *sport = container_of(work, struct ttyi3c_port, rxwork); + struct i3c_priv_xfer xfers; + u32 retry = I3C_TTY_RETRY; + u16 status; + int ret; + + memset(&xfers, 0, sizeof(xfers)); + xfers.data.in = sport->rx_buff; + xfers.len = I3C_TTY_TRANS_SIZE; + xfers.rnw = 1; + + do { + if (test_bit(I3C_TTY_RX_STOP, &sport->status)) + break; + + i3c_device_do_priv_xfers(sport->i3cdev, &xfers, 1); + + if (xfers.actual_len) { + ret = tty_insert_flip_string(&sport->port, sport->rx_buff, + xfers.actual_len); + if (ret < xfers.actual_len) + sport->buf_overrun++; + + retry = I3C_TTY_RETRY; + continue; + } + + status = I3C_TTY_TARGET_RX_READY; + i3c_device_getstatus_format1(sport->i3cdev, &status); + /* + * Target side needs some time to fill data into fifo. Target side may not + * have hardware update status in real time. Software update status always + * needs some delays. + * + * Generally, target side have circular buffer in memory, it will be moved + * into FIFO by CPU or DMA. 'status' just show if circular buffer empty. But + * there are gap, especially CPU have not response irq to fill FIFO in time. + * So xfers.actual will be zero, wait for little time to avoid flood + * transfer in i3c bus. + */ + usleep_range(I3C_TTY_YIELD_US, 10 * I3C_TTY_YIELD_US); + retry--; + + } while (retry && (status & I3C_TTY_TARGET_RX_READY)); + + tty_flip_buffer_push(&sport->port); +} + +static void tty_i3c_txwork(struct work_struct *work) +{ + struct ttyi3c_port *sport = container_of(work, struct ttyi3c_port, txwork); + struct i3c_priv_xfer xfers; + u32 retry = I3C_TTY_RETRY; + unsigned long flags; + int ret; + + xfers.rnw = 0; + xfers.data.out = sport->tx_buff; + + while (!kfifo_is_empty(&sport->port.xmit_fifo)) { + spin_lock_irqsave(&sport->xlock, flags); + xfers.len = kfifo_out_peek(&sport->port.xmit_fifo, sport->tx_buff, + I3C_TTY_TRANS_SIZE); + spin_unlock_irqrestore(&sport->xlock, flags); + ret = i3c_device_do_priv_xfers(sport->i3cdev, &xfers, 1); + if (ret) { + /* + * Target side may not move data out of FIFO. delay can't resolve problem, + * just reduce some possiblity. Target can't end I3C SDR mode write + * transfer, discard data is reasonable when FIFO overrun. + */ + usleep_range(I3C_TTY_YIELD_US, 10 * I3C_TTY_YIELD_US); + retry--; + } else { + retry = I3C_TTY_RETRY; + } + + if (ret == 0 || retry == 0) { + /* when retry == 0, means need discard the data */ + spin_lock_irqsave(&sport->xlock, flags); + ret = kfifo_out(&sport->port.xmit_fifo, sport->tx_buff, xfers.len); + spin_unlock_irqrestore(&sport->xlock, flags); + } + } + + spin_lock_irqsave(&sport->xlock, flags); + if (kfifo_len(&sport->port.xmit_fifo) < WAKEUP_CHARS) + tty_port_tty_wakeup(&sport->port); + spin_unlock_irqrestore(&sport->xlock, flags); +} + +static int i3c_probe(struct i3c_device *i3cdev) +{ + struct ttyi3c_port *sport; + struct device *tty_dev; + struct i3c_ibi_setup req; + int minor; + int ret; + + sport = devm_kzalloc(&i3cdev->dev, sizeof(*sport), GFP_KERNEL); + if (!sport) + return -ENOMEM; + + sport->i3cdev = i3cdev; + + dev_set_drvdata(&i3cdev->dev, sport); + + req.max_payload_len = 8; + req.num_slots = 4; + req.handler = &i3c_controller_irq_handler; + + ret = i3c_device_request_ibi(i3cdev, &req); + if (ret) + return -EINVAL; + + mutex_lock(&i3c_tty_minors_lock); + minor = idr_alloc(&i3c_tty_minors, sport, 0, I3C_TTY_MINORS, GFP_KERNEL); + mutex_unlock(&i3c_tty_minors_lock); + + if (minor < 0) { + ret = -EINVAL; + goto err_idr_alloc; + } + + spin_lock_init(&sport->xlock); + INIT_WORK(&sport->txwork, tty_i3c_txwork); + INIT_WORK(&sport->rxwork, tty_i3c_rxwork); + init_completion(&sport->txcomplete); + + tty_port_init(&sport->port); + sport->port.ops = &i3c_port_ops; + + tty_dev = tty_port_register_device(&sport->port, i3c_tty_driver, minor, + &i3cdev->dev); + if (IS_ERR(tty_dev)) { + ret = PTR_ERR(tty_dev); + goto err_tty_port_register; + } + + sport->minor = minor; + + return 0; + +err_tty_port_register: + tty_port_put(&sport->port); + + mutex_lock(&i3c_tty_minors_lock); + idr_remove(&i3c_tty_minors, minor); + mutex_unlock(&i3c_tty_minors_lock); + +err_idr_alloc: + i3c_device_free_ibi(i3cdev); + + return ret; +} + +static void i3c_remove(struct i3c_device *dev) +{ + struct ttyi3c_port *sport = dev_get_drvdata(&dev->dev); + + tty_port_unregister_device(&sport->port, i3c_tty_driver, sport->minor); + cancel_work_sync(&sport->txwork); + + tty_port_put(&sport->port); + + mutex_lock(&i3c_tty_minors_lock); + idr_remove(&i3c_tty_minors, sport->minor); + mutex_unlock(&i3c_tty_minors_lock); + + i3c_device_free_ibi(sport->i3cdev); +} + +static struct i3c_driver i3c_driver = { + .driver = { + .name = "ttyi3c", + }, + .probe = i3c_probe, + .remove = i3c_remove, + .id_table = i3c_ids, +}; + +static int __init i3c_tty_init(void) +{ + int ret; + + i3c_tty_driver = tty_alloc_driver(I3C_TTY_MINORS, + TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); + + if (IS_ERR(i3c_tty_driver)) + return PTR_ERR(i3c_tty_driver); + + i3c_tty_driver->driver_name = "ttyI3C"; + i3c_tty_driver->name = "ttyI3C"; + i3c_tty_driver->minor_start = 0, + i3c_tty_driver->type = TTY_DRIVER_TYPE_SERIAL, + i3c_tty_driver->subtype = SERIAL_TYPE_NORMAL, + i3c_tty_driver->init_termios = tty_std_termios; + i3c_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | + CLOCAL; + i3c_tty_driver->init_termios.c_lflag = 0; + + tty_set_operations(i3c_tty_driver, &i3c_tty_ops); + + ret = tty_register_driver(i3c_tty_driver); + if (ret) + goto err_tty_register_driver; + + ret = i3c_driver_register(&i3c_driver); + if (ret) + goto err_i3c_driver_register; + + return 0; + +err_i3c_driver_register: + tty_unregister_driver(i3c_tty_driver); + +err_tty_register_driver: + tty_driver_kref_put(i3c_tty_driver); + + return ret; +} + +static void __exit i3c_tty_exit(void) +{ + i3c_driver_unregister(&i3c_driver); + tty_unregister_driver(i3c_tty_driver); + tty_driver_kref_put(i3c_tty_driver); + idr_destroy(&i3c_tty_minors); +} + +module_init(i3c_tty_init); +module_exit(i3c_tty_exit); + +MODULE_LICENSE("GPL");