get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2195289/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2195289,
    "url": "http://patchwork.ozlabs.org/api/patches/2195289/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linux-gpio/patch/20260210170814.406883-4-shenwei.wang@nxp.com/",
    "project": {
        "id": 42,
        "url": "http://patchwork.ozlabs.org/api/projects/42/?format=api",
        "name": "Linux GPIO development",
        "link_name": "linux-gpio",
        "list_id": "linux-gpio.vger.kernel.org",
        "list_email": "linux-gpio@vger.kernel.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260210170814.406883-4-shenwei.wang@nxp.com>",
    "list_archive_url": null,
    "date": "2026-02-10T17:08:13",
    "name": "[v7,3/4] gpio: rpmsg: add generic rpmsg GPIO driver",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "ccde79c6687e55310491d494e348823bb3e0255a",
    "submitter": {
        "id": 74153,
        "url": "http://patchwork.ozlabs.org/api/people/74153/?format=api",
        "name": "Shenwei Wang",
        "email": "shenwei.wang@nxp.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linux-gpio/patch/20260210170814.406883-4-shenwei.wang@nxp.com/mbox/",
    "series": [
        {
            "id": 491712,
            "url": "http://patchwork.ozlabs.org/api/series/491712/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/linux-gpio/list/?series=491712",
            "date": "2026-02-10T17:04:37",
            "name": null,
            "version": 7,
            "mbox": "http://patchwork.ozlabs.org/series/491712/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2195289/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2195289/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "\n <linux-gpio+bounces-31567-incoming=patchwork.ozlabs.org@vger.kernel.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "linux-gpio@vger.kernel.org"
        ],
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=nxp.com header.i=@nxp.com header.a=rsa-sha256\n header.s=selector1 header.b=Y6JCKbQp;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=172.232.135.74; helo=sto.lore.kernel.org;\n envelope-from=linux-gpio+bounces-31567-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)",
            "smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=nxp.com header.i=@nxp.com\n header.b=\"Y6JCKbQp\"",
            "smtp.subspace.kernel.org;\n arc=fail smtp.client-ip=40.107.162.10",
            "smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=nxp.com",
            "smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=nxp.com",
            "dkim=none (message not signed)\n header.d=none;dmarc=none action=none header.from=nxp.com;"
        ],
        "Received": [
            "from sto.lore.kernel.org (sto.lore.kernel.org [172.232.135.74])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4f9Shc3hq4z1xwG\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 11 Feb 2026 04:09:04 +1100 (AEDT)",
            "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sto.lore.kernel.org (Postfix) with ESMTP id 2BEA2300B443\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 10 Feb 2026 17:08:58 +0000 (UTC)",
            "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 428F13803DC;\n\tTue, 10 Feb 2026 17:08:57 +0000 (UTC)",
            "from PA4PR04CU001.outbound.protection.outlook.com\n (mail-francecentralazon11013010.outbound.protection.outlook.com\n [40.107.162.10])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id CC4BC32ABF6;\n\tTue, 10 Feb 2026 17:08:54 +0000 (UTC)",
            "from PAXPR04MB9185.eurprd04.prod.outlook.com (2603:10a6:102:231::11)\n by FRWPR04MB11284.eurprd04.prod.outlook.com (2603:10a6:d10:19e::8) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9611.8; Tue, 10 Feb\n 2026 17:08:51 +0000",
            "from PAXPR04MB9185.eurprd04.prod.outlook.com\n ([fe80::b4c0:6119:2228:2ceb]) by PAXPR04MB9185.eurprd04.prod.outlook.com\n ([fe80::b4c0:6119:2228:2ceb%4]) with mapi id 15.20.9611.006; Tue, 10 Feb 2026\n 17:08:51 +0000"
        ],
        "ARC-Seal": [
            "i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1770743337; cv=fail;\n b=jOcVFtDIlZpfheAjqdPi6kcwk3j5X7YgPTTKX2BMU5HuncthbK/K+mK9mr8MiMUOBoqYUAxER9ES9pGYkGqV4iXjOhk+DHU9OL2NHDGEpUsryUX8SpiqDkEjk7EwSPWc9tM1SOVmriR5s7XKcJ9yIko8SPgon0DQFLAUGSMFrR0=",
            "i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;\n b=pDv8DaQssNxGqsbdKxb0aRZ2OMtFzrWsBE9kWKptDzcstmkZSUcEopYxKNqiYu4lnHytKLutonsO+JA2A2pDF1yApHS3a3BhlrCEIhdwkbsAwPpFI0y2xrNrAp/3sFfkkeE5ROAopVzR4Tr1jcw6XT5MvCgCl6/KW+V17lAfBZE3B0PcRsT6Jq4R2ByXXmuBBSRANEXRbLk4Svu2stp85J/WONF12tj0FgyHKbhedh8uEW8ZYLdxfzGxhR15lTiXo4DI17125YNdZRIGhh6iJb88rmELsI7X1u13CzT842ghpx8BUQddCDrliMo6opLwFchJdLoCqBpOD0hJgaKu5A=="
        ],
        "ARC-Message-Signature": [
            "i=2; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1770743337; c=relaxed/simple;\n\tbh=IUbXczJdUryHr3ghtGFlioWLWNHknfNVsDIEVGSmIBM=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t Content-Type:MIME-Version;\n b=SoZ8hGItwmq85JLLctS5But+aPh3XBmpgSTHwr19y/fw+KZWG0/LhbUESQy1o3tm7z5frTTuq4+n23ktdvIjkG3auzBbOGMJLCXOe3QC0QBzojm+xdkEJJU2sNFw4KKKPjFi3v1gg7aENuDqa9Cia47nL7u3Rn06Ao5fRZLxdZs=",
            "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector10001;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;\n bh=pcN7mSi9E44BPAMmSWYuMLIpJiui0LAfPQmHKjLFiVg=;\n b=VxhLC6jB1TcFTgfKbqYoF+LkDVxY/EH/hGUMZ5YP1L8aVzP9gyEEcpHV2b+CTEZ4qHTXLsUXdUTjKeCgyZ8TXLCnlz3hI9/FdEqP9LrhZMmXt8WtaVwjN1DtvFiqA2civqRNhOBglPFRgo+gxn4HUA0/BFdLdrkKtMO5qs0Hmxi2VAI6i7NP+xCOnIxIoDABKWO6FGT993cyZqsseGdEl7qUAFuulhrIF7BEywq+6HsaE4m20gtq83ViiGft5cZVDHKf9tqZX8txjKeomJPTl7BEmwWpZNsQXB2FfsoyvkPGZ9eZjdDgjnJw6mNR8UZ9YVtgh5dzU0979yXy0ptPIQ=="
        ],
        "ARC-Authentication-Results": [
            "i=2; smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=nxp.com;\n spf=pass smtp.mailfrom=nxp.com;\n dkim=pass (2048-bit key) header.d=nxp.com header.i=@nxp.com\n header.b=Y6JCKbQp; arc=fail smtp.client-ip=40.107.162.10",
            "i=1; mx.microsoft.com 1; spf=pass\n smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass\n header.d=nxp.com; arc=none"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=pcN7mSi9E44BPAMmSWYuMLIpJiui0LAfPQmHKjLFiVg=;\n b=Y6JCKbQpFhYZfLJXJ8Wmdxrc8mNWDmtvcT7wgqDA0TgVRjovgBU5jt5opNgR1V0X2hyS2E5BUnBCxrKpSvXE6yj84GNX8y7ulyhZoodcuCjMMai0KwFqP2Ujx79ccV2dpiIjBaadBncV4n59Q87uMQdWlaBrGgWgLw4VF0xSx/vDJt9oy7k5TN9wQ/BJp7ItVdLl2PNnDzSe5wkcOyZLkVccdgjOp2YquxwULaxZ0LzEKr53fPkYQ0n+MPeLUGFB6EQ4wyLQqa7PJJHKYCh34c5JjtrELeSOaG4HwvyJqeR61XjlFWWXvkLxtaBNKwm3RFY8XvUS1T+6vxdvDyN9LA==",
        "From": "Shenwei Wang <shenwei.wang@nxp.com>",
        "To": "Linus Walleij <linusw@kernel.org>,\n\tBartosz Golaszewski <brgl@kernel.org>,\n\tRob Herring <robh@kernel.org>,\n\tKrzysztof Kozlowski <krzk+dt@kernel.org>,\n\tConor Dooley <conor+dt@kernel.org>,\n\tBjorn Andersson <andersson@kernel.org>,\n\tMathieu Poirier <mathieu.poirier@linaro.org>,\n\tShawn Guo <shawnguo@kernel.org>,\n\tSascha Hauer <s.hauer@pengutronix.de>,\n\tJonathan Corbet <corbet@lwn.net>",
        "Cc": "Pengutronix Kernel Team <kernel@pengutronix.de>,\n\tFabio Estevam <festevam@gmail.com>,\n\tShenwei Wang <shenwei.wang@nxp.com>,\n\tPeng Fan <peng.fan@nxp.com>,\n\tlinux-gpio@vger.kernel.org,\n\tdevicetree@vger.kernel.org,\n\tlinux-kernel@vger.kernel.org,\n\tlinux-remoteproc@vger.kernel.org,\n\timx@lists.linux.dev,\n\tlinux-arm-kernel@lists.infradead.org,\n\tlinux-doc@vger.kernel.org,\n\tlinux-imx@nxp.com,\n\tarnaud.pouliquen@foss.st.com,\n\tBartosz Golaszewski <brgl@bgdev.pl>,\n\tAndrew Lunn <andrew@lunn.ch>",
        "Subject": "[PATCH v7 3/4] gpio: rpmsg: add generic rpmsg GPIO driver",
        "Date": "Tue, 10 Feb 2026 11:08:13 -0600",
        "Message-ID": "<20260210170814.406883-4-shenwei.wang@nxp.com>",
        "X-Mailer": "git-send-email 2.43.0",
        "In-Reply-To": "<20260210170814.406883-1-shenwei.wang@nxp.com>",
        "References": "<20260210170814.406883-1-shenwei.wang@nxp.com>",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-ClientProxiedBy": "SJ0PR03CA0130.namprd03.prod.outlook.com\n (2603:10b6:a03:33c::15) To PAXPR04MB9185.eurprd04.prod.outlook.com\n (2603:10a6:102:231::11)",
        "Precedence": "bulk",
        "X-Mailing-List": "linux-gpio@vger.kernel.org",
        "List-Id": "<linux-gpio.vger.kernel.org>",
        "List-Subscribe": "<mailto:linux-gpio+subscribe@vger.kernel.org>",
        "List-Unsubscribe": "<mailto:linux-gpio+unsubscribe@vger.kernel.org>",
        "MIME-Version": "1.0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-TrafficTypeDiagnostic": "PAXPR04MB9185:EE_|FRWPR04MB11284:EE_",
        "X-MS-Office365-Filtering-Correlation-Id": "a96ebb43-a9b1-4974-29b7-08de68c70fe5",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "\n\tBCL:0;ARA:13230040|52116014|376014|7416014|1800799024|19092799006|366016|38350700014|921020;",
        "X-Microsoft-Antispam-Message-Info": "\n DDRKj4AIeWMsj1qZbVm/nOxenC0AvRHYZjfNZ9yXFpMkmnrYv8Cw+Xmga59joyzM3cqusxqzgqVWwqxNgL8wYGar4D168rcrVycEekRb0mlA6UJu0NqGMTh/2rCNLbnhqThNOM2bkmsV7zoHWZSkcxrdcjGQUcoESFBBrUWJA8+LapJsSXKXNUx+y/b7q7YR+FiDlftLpu217wkpvDNSstmNdY/UtcJNSeMM8JHlvdfnIJZrW84s6sxtBywi9kqNnirySv1LI2ZzclsVkHq1sMlb1UZBsit2O+ZNFOnN4a6vbipS5otfW5JBZxIVthNHygrHVLFRMyp06GCLDK6QyYsJ2LfrOOb2C8v2+H9CKTQwLPihqfWucjfYcEvcwZ/dPOJdemcCdBgsNqFmQYQYG/EUsWEiM4eF4WHpmZQvUpcioAbNleWcRDjLQBHSPYIdTkRzK+UC2QSG54hBM9TI3ZaP+fJZ3EcmVF3WjUn86AoZO1anMyxn2uAuyRPTE1IuKXs4fB59yMYWsP79ZkLG8QORVHtz1MBYpKnjcrIw6+FsCJ6SAFrAUuazt8dQMYREdtqPewsX+UxDVTMyvtfp9N4stJ7DZr5SQIBt3BPa5r77lJajSxBPq/ADnf5cjRq/jp4w+rzL5tgrb4BUVMnnRQbdnLyTLmO8IOM8iWG8+IQakTH2REW96WGei+gHUKsfq1cQPBnkC+Pk/p5l+9PpdslW2hmXMu9Rl3bmNVa11DH5P7sOW+yjLJ/1n9WB/DNhQe0HqmcU6EJGyccQIi/3fuyzXj8hWvQ5fPI2IuFcaDW0WeCR4I+QLWONZpek533yrWBrhGzC1//xDyrhU4BEyxxTmfXw6BmOgiegkllyxsnCuJUjpR7AproJw1opk9WgytF0bx5s2aMx1bNO3lBoZGr+mynBPczG8ul1FRQ/eRoxBATfAMAenC69ZFuYCnClZKvgv3VkRzzUMI48Ivz4UCJa0UefrP5JS6JQPdezqmfT+cZLx0ASIKz9fCpP1U2qw1a/VlibLwbBCm/5kGwVGIDDNDGwdmP2cYMPrLKpvQBrnPYCyGlcj/ibROkoxY5gS8BbaMeRYrnYOM3EApFn12zuRo8VLEVNHbcRXl2Y2OgqjoqY5z/IdayGad8RnqPrWwZWZvLgqs7E1OXMx4ymLqhWYTHikucH8i/1t75HN2cUbmg+rPJgEh4xpG7QbKi1bvzO1nQewFNy5K6h52LW3TiPMh/Lx7CeiRpAB2QEILUnGciooDvZMKH/DKvEy/CLWfhG1EZbRywaI0KAb0Rk+vzPAe5Bf/fQNrT0XIYs4V6wJQV973+C2/XpCBG93+YAVBgHq20BgJekIBInL8cUDvzVdAKnWqXa6ngKX3HYxlrnxOf3OoTvqZ0Npr4+dHxwJAzp+kjI2xlF0+oIQlKo/M4NTjzEDfgpuFFRyc8FiyxrVFUvxRQLfKzuDql5YtQJtc6eqiqFyjFl7g4AnMPiEIUBgiPb3SmGRGT/hCt4MU5p8EaNablNmMbe0YYktEdi/K371++NH33DXWm34I0Oqo6WzIXDhVFvCttunIVthVEfhxYC6Wr31q2wOV98RKrKFxO8fIPt3kBbrX6IbxyYp9/b8GeckfbMSJjM9VFtokY8ZGoJjCft3GTthbG0Aia5",
        "X-Forefront-Antispam-Report": "\n\tCIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PAXPR04MB9185.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(52116014)(376014)(7416014)(1800799024)(19092799006)(366016)(38350700014)(921020);DIR:OUT;SFP:1101;",
        "X-MS-Exchange-AntiSpam-MessageData-ChunkCount": "1",
        "X-MS-Exchange-AntiSpam-MessageData-0": "\n dewXIyNFGHhP7fXFkCRHh5Ulbna1tOiC4iYqyjUqzjGplndqewcojD9p2QghUVzDwjiC41LsRIbEnaxojLaTIGR3I3snKYpwWv/ZQAdouveCzuEy6ssHtCsyVkccIkGZFtT68+fHYjg1A8yhqw+aDQgD7IUYSe7xJzA1GZRtp/tzehfwOtXyQfkpRUG2Twx3dutmiAqXjeHHE1Np/yWhKmQbxfEAiWg67m2YUNFOWrVbouss938Be6e9jm/4Qy8CanaTiH+LWJn/XHvP65Y+iSdxQmwi6MRQYCELx7NhnuRQw/O6baBWr5uVipkEijL6ffm8KBQSRrdZSq1M+9orG+nSpB2GopS9dMqNPKFBwBwkNOmSklgrbpwntGq8Fg4nmAKiZdOXaoKZUHviJifuBJMtd5tNhtPFKrlBq8UcabLpDk0Pa3crO50CexfO3+nFP6uWuDb5kM68JFdD7WPaH7FGjQ6B/ylHtpd2z/L4qiX4I0i+ZOJk+IGYyUjo+QyXPcJWAfTMYgcp/W6E3vemoWRpRXUO6YYo5tt6/9K35oSbisHRSKfzjdu2f6+ICmn6QLs12oUVW6FLb5MTNpxfmm1nKRbWYUY9/Pv0WSrLMD5CUZi3ctw28EUxh1g53rPZpTY8FrugIIOdX3/jiuE7WJR0JP3/oFK8YOrvXqGxUsRcFQMYEWK9sbyDw14sdL9ww1iF7CwKsMapQp41Cx3j2oxX+At1T10LnysOuEBiY3CpQa55ULkUC3Dr4Awf5w+fF0emfRX99jQDn5PgayD/dWIC46EmBGPbTIml8EbcejyFpdiJvBwgaufp1K/XB0gX5lXSed1V70/bGHr5d9BolGHEx0Kdnm+YozNdTDAwtpICVFMBb6S5l+gKrk1K5TmG14kphFlfBTATUhJYoRqeqhNeBAvLpzyx4IJkD3aXbuKyhFI9eTPCuepV2gZwzfO3fZmBYKjwVfGPYRTpNLADrONeyWy+ntVrilUStX/8XD31yGTR5gOSQLm5msmKJOAz5hs/4zVf2lzbNg5rhDfyi5RZYXmv0BpK00Q9swGR7abmGLcdtsHEVqrCzJLoVKnfey/zSoSNKZu0Vj08xPwzNEVHuxkzLiS2f1RcxjDdSUc+pwM3CUS6L9VBrIy7Rcc3DOopqgvKAr2acblTttCYCcf4x+szrE3jh8nW83Q2hEv6klKxuPSzv0drIjk4xRZuRsIUTzTdwNzuMzQ9MuVpM5bj7QFEWGE31oGlQWkHW6od1gNBT784J9v2gsbHd2Egi/OsBXbnKtiAdPKtqMKl48wFPHPUO5m3bACt206bq8jvSYCyJuHXK4l/zNiZ5exGeinhQ4y40t/MAPXwV/9s0mFyaHuPRaKr8JF0E9a9qOk4b3eI2Kz88YI/pyxNEFkyVGgV6Tgp2+gV4S2z+PE9XnTEclRco6AIZctxiItN/cOJ8F8UhJsU12fGcDbm4WynHNzfVYMpeiCL7XHsSQX26KNjKL9PT4EXkhoewOi0nSxORSmhSQslYdi/Kv1IvG6A8Wm8ivVQ6YEbDz/qnRSd5Ypz9k/V9IZkjMOMhdCT3peJqFb6Edf4C83NxVtKvZQgCCQeVApagj5oDdKBfyFW/D5IJS1hWkcks84W+0/oJtWZ67DBlWhmQ0JIUpQZPmGDyEErvOKBrjrSTdhmNYrbBszw2yKXcJFw8Svs0yw3nn//u4tPWDJO6Sz03KtTYiZDoLHiOTV1GiQAEI40KZXZIw==",
        "X-OriginatorOrg": "nxp.com",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n a96ebb43-a9b1-4974-29b7-08de68c70fe5",
        "X-MS-Exchange-CrossTenant-AuthSource": "PAXPR04MB9185.eurprd04.prod.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Internal",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "10 Feb 2026 17:08:51.0442\n (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": "\n jV4I2KvSgYulfLc3vhO/HRK/3c37QA8t1n/qyWMGj8BD1x2eeRu0SYR9kL2c/IcgdhpBX4pSfsKxSmn9gu5ZKw==",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "FRWPR04MB11284"
    },
    "content": "On an AMP platform, the system may include two processors:\n\t- An MCU running an RTOS\n\t- An MPU running Linux\n\nThese processors communicate via the RPMSG protocol.\nThe driver implements the standard GPIO interface, allowing\nthe Linux side to control GPIO controllers which reside in\nthe remote processor via RPMSG protocol.\n\nCc: Bartosz Golaszewski <brgl@bgdev.pl>\nCc: Andrew Lunn <andrew@lunn.ch>\nSigned-off-by: Shenwei Wang <shenwei.wang@nxp.com>\n---\n drivers/gpio/Kconfig      |  16 ++\n drivers/gpio/Makefile     |   1 +\n drivers/gpio/gpio-rpmsg.c | 583 ++++++++++++++++++++++++++++++++++++++\n 3 files changed, 600 insertions(+)\n create mode 100644 drivers/gpio/gpio-rpmsg.c",
    "diff": "diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig\nindex bd185482a7fd..00ea0c1d8035 100644\n--- a/drivers/gpio/Kconfig\n+++ b/drivers/gpio/Kconfig\n@@ -1883,6 +1883,22 @@ config GPIO_SODAVILLE\n \n endmenu\n \n+menu \"RPMSG GPIO drivers\"\n+\tdepends on RPMSG\n+\n+config GPIO_RPMSG\n+\ttristate \"Generic RPMSG GPIO support\"\n+\tselect GPIOLIB_IRQCHIP\n+\tdefault REMOTEPROC\n+\thelp\n+\t  Say yes here to support the generic GPIO functions over the RPMSG\n+\t  bus. Currently supported devices: i.MX7ULP, i.MX8ULP, i.MX8x, and\n+\t  i.MX9x.\n+\n+\t  If unsure, say N.\n+\n+endmenu\n+\n menu \"SPI GPIO expanders\"\n \tdepends on SPI_MASTER\n \ndiff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile\nindex 2421a8fd3733..b1373ec274c8 100644\n--- a/drivers/gpio/Makefile\n+++ b/drivers/gpio/Makefile\n@@ -156,6 +156,7 @@ obj-$(CONFIG_GPIO_RDC321X)\t\t+= gpio-rdc321x.o\n obj-$(CONFIG_GPIO_REALTEK_OTTO)\t\t+= gpio-realtek-otto.o\n obj-$(CONFIG_GPIO_REG)\t\t\t+= gpio-reg.o\n obj-$(CONFIG_GPIO_ROCKCHIP)\t+= gpio-rockchip.o\n+obj-$(CONFIG_GPIO_RPMSG)\t\t+= gpio-rpmsg.o\n obj-$(CONFIG_GPIO_RTD)\t\t\t+= gpio-rtd.o\n obj-$(CONFIG_ARCH_SA1100)\t\t+= gpio-sa1100.o\n obj-$(CONFIG_GPIO_SAMA5D2_PIOBU)\t+= gpio-sama5d2-piobu.o\ndiff --git a/drivers/gpio/gpio-rpmsg.c b/drivers/gpio/gpio-rpmsg.c\nnew file mode 100644\nindex 000000000000..8c235d9dc336\n--- /dev/null\n+++ b/drivers/gpio/gpio-rpmsg.c\n@@ -0,0 +1,583 @@\n+// SPDX-License-Identifier: GPL-2.0-only\n+/*\n+ * Copyright 2026 NXP\n+ *\n+ * The driver exports a standard gpiochip interface to control\n+ * the GPIO controllers via RPMSG on a remote processor.\n+ */\n+#include <linux/completion.h>\n+#include <linux/device.h>\n+#include <linux/err.h>\n+#include <linux/gpio/driver.h>\n+#include <linux/init.h>\n+#include <linux/irqdomain.h>\n+#include <linux/mod_devicetable.h>\n+#include <linux/module.h>\n+#include <linux/mutex.h>\n+#include <linux/of.h>\n+#include <linux/of_device.h>\n+#include <linux/of_platform.h>\n+#include <linux/platform_device.h>\n+#include <linux/remoteproc.h>\n+#include <linux/rpmsg.h>\n+\n+#define RPMSG_GPIO_ID\t\t5\n+#define RPMSG_VENDOR\t\t1\n+#define RPMSG_VERSION\t\t0\n+\n+#define GPIOS_PER_PORT\t\t32\n+#define RPMSG_TIMEOUT\t\t1000\n+\n+/* GPIO RPMSG header type */\n+#define GPIO_RPMSG_SETUP\t0\n+#define GPIO_RPMSG_REPLY\t1\n+#define GPIO_RPMSG_NOTIFY\t2\n+\n+/* GPIO Interrupt trigger type */\n+#define GPIO_RPMSG_TRI_IGNORE\t\t0\n+#define GPIO_RPMSG_TRI_RISING\t\t1\n+#define GPIO_RPMSG_TRI_FALLING\t\t2\n+#define GPIO_RPMSG_TRI_BOTH_EDGE\t3\n+#define GPIO_RPMSG_TRI_LOW_LEVEL\t4\n+#define GPIO_RPMSG_TRI_HIGH_LEVEL\t5\n+\n+/* GPIO RPMSG commands */\n+#define GPIO_RPMSG_INPUT_INIT\t\t0\n+#define GPIO_RPMSG_OUTPUT_INIT\t\t1\n+#define GPIO_RPMSG_INPUT_GET\t\t2\n+#define GPIO_RPMSG_DIRECTION_GET\t3\n+\n+#define MAX_PORT_PER_CHANNEL    10\n+\n+/*\n+ * @rproc_name: the name of the remote proc.\n+ * @channel_devices: an array of the devices related to the rpdev.\n+ */\n+struct rpdev_drvdata {\n+\tconst char *rproc_name;\n+\tvoid *channel_devices[MAX_PORT_PER_CHANNEL];\n+};\n+\n+struct gpio_rpmsg_head {\n+\tu8 id;\t\t/* Message ID Code */\n+\tu8 vendor;\t/* Vendor ID number */\n+\tu8 version;\t/* Vendor-specific version number */\n+\tu8 type;\t/* Message type */\n+\tu8 cmd;\t\t/* Command code */\n+\tu8 reserved[5];\n+} __packed;\n+\n+struct gpio_rpmsg_packet {\n+\tstruct gpio_rpmsg_head header;\n+\tu8 pin_idx;\n+\tu8 port_idx;\n+\tunion {\n+\t\tu8 event;\n+\t\tu8 retcode;\n+\t\tu8 value;\n+\t} out;\n+\tunion {\n+\t\tu8 wakeup;\n+\t\tu8 value;\n+\t} in;\n+} __packed __aligned(8);\n+\n+struct gpio_rpmsg_pin {\n+\tu8 irq_shutdown;\n+\tu8 irq_unmask;\n+\tu8 irq_mask;\n+\tu32 irq_wake_enable;\n+\tu32 irq_type;\n+\tstruct gpio_rpmsg_packet msg;\n+};\n+\n+struct gpio_rpmsg_info {\n+\tstruct rpmsg_device *rpdev;\n+\tstruct gpio_rpmsg_packet *reply_msg;\n+\tstruct completion cmd_complete;\n+\tstruct mutex lock;\n+\tvoid **port_store;\n+};\n+\n+struct rpmsg_gpio_port {\n+\tstruct gpio_chip gc;\n+\tstruct gpio_rpmsg_pin gpio_pins[GPIOS_PER_PORT];\n+\tstruct gpio_rpmsg_info info;\n+\tint idx;\n+};\n+\n+static int gpio_send_message(struct rpmsg_gpio_port *port,\n+\t\t\t     struct gpio_rpmsg_packet *msg,\n+\t\t\t     bool sync)\n+{\n+\tstruct gpio_rpmsg_info *info = &port->info;\n+\tint err;\n+\n+\treinit_completion(&info->cmd_complete);\n+\terr = rpmsg_send(info->rpdev->ept, msg, sizeof(struct gpio_rpmsg_packet));\n+\tif (err) {\n+\t\tdev_err(&info->rpdev->dev, \"rpmsg_send failed: %d\\n\", err);\n+\t\treturn err;\n+\t}\n+\n+\tif (sync) {\n+\t\terr = wait_for_completion_timeout(&info->cmd_complete,\n+\t\t\t\t\t\t  msecs_to_jiffies(RPMSG_TIMEOUT));\n+\t\tif (!err) {\n+\t\t\tdev_err(&info->rpdev->dev, \"rpmsg_send timeout!\\n\");\n+\t\t\treturn -ETIMEDOUT;\n+\t\t}\n+\n+\t\tif (info->reply_msg->out.retcode != 0) {\n+\t\t\tdev_err(&info->rpdev->dev, \"remote core replies an error: %d!\\n\",\n+\t\t\t\tinfo->reply_msg->out.retcode);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\t/* copy the reply message */\n+\t\tmemcpy(&port->gpio_pins[info->reply_msg->pin_idx].msg,\n+\t\t       info->reply_msg, sizeof(*info->reply_msg));\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static struct gpio_rpmsg_packet *gpio_setup_msg_header(struct rpmsg_gpio_port *port,\n+\t\t\t\t\t\t       unsigned int offset,\n+\t\t\t\t\t\t       u8 cmd)\n+{\n+\tstruct gpio_rpmsg_packet *msg = &port->gpio_pins[offset].msg;\n+\n+\tmemset(msg, 0, sizeof(struct gpio_rpmsg_packet));\n+\tmsg->header.id = RPMSG_GPIO_ID;\n+\tmsg->header.vendor = RPMSG_VENDOR;\n+\tmsg->header.version = RPMSG_VERSION;\n+\tmsg->header.type = GPIO_RPMSG_SETUP;\n+\tmsg->header.cmd = cmd;\n+\tmsg->pin_idx = offset;\n+\tmsg->port_idx = port->idx;\n+\n+\treturn msg;\n+}\n+\n+static int rpmsg_gpio_get(struct gpio_chip *gc, unsigned int gpio)\n+{\n+\tstruct rpmsg_gpio_port *port = gpiochip_get_data(gc);\n+\tstruct gpio_rpmsg_packet *msg;\n+\tint ret;\n+\n+\tguard(mutex)(&port->info.lock);\n+\n+\tmsg = gpio_setup_msg_header(port, gpio, GPIO_RPMSG_INPUT_GET);\n+\n+\tret = gpio_send_message(port, msg, true);\n+\tif (!ret)\n+\t\tret = !!port->gpio_pins[gpio].msg.in.value;\n+\n+\treturn ret;\n+}\n+\n+static int rpmsg_gpio_get_direction(struct gpio_chip *gc, unsigned int gpio)\n+{\n+\tstruct rpmsg_gpio_port *port = gpiochip_get_data(gc);\n+\tstruct gpio_rpmsg_packet *msg;\n+\tint ret;\n+\n+\tguard(mutex)(&port->info.lock);\n+\n+\tmsg = gpio_setup_msg_header(port, gpio, GPIO_RPMSG_DIRECTION_GET);\n+\n+\tret = gpio_send_message(port, msg, true);\n+\tif (!ret)\n+\t\tret = !!port->gpio_pins[gpio].msg.in.value;\n+\n+\treturn ret;\n+}\n+\n+static int rpmsg_gpio_direction_input(struct gpio_chip *gc, unsigned int gpio)\n+{\n+\tstruct rpmsg_gpio_port *port = gpiochip_get_data(gc);\n+\tstruct gpio_rpmsg_packet *msg;\n+\n+\tguard(mutex)(&port->info.lock);\n+\n+\tmsg = gpio_setup_msg_header(port, gpio, GPIO_RPMSG_INPUT_INIT);\n+\n+\treturn gpio_send_message(port, msg, true);\n+}\n+\n+static int rpmsg_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)\n+{\n+\tstruct rpmsg_gpio_port *port = gpiochip_get_data(gc);\n+\tstruct gpio_rpmsg_packet *msg;\n+\n+\tguard(mutex)(&port->info.lock);\n+\n+\tmsg = gpio_setup_msg_header(port, gpio, GPIO_RPMSG_OUTPUT_INIT);\n+\tmsg->out.value = val;\n+\n+\treturn gpio_send_message(port, msg, true);\n+}\n+\n+static int rpmsg_gpio_direction_output(struct gpio_chip *gc,\n+\t\t\t\t       unsigned int gpio,\n+\t\t\t\t       int val)\n+{\n+\treturn rpmsg_gpio_set(gc, gpio, val);\n+}\n+\n+static int gpio_rpmsg_irq_set_type(struct irq_data *d, u32 type)\n+{\n+\tstruct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);\n+\tu32 gpio_idx = d->hwirq;\n+\tint edge = 0;\n+\tint ret = 0;\n+\n+\tswitch (type) {\n+\tcase IRQ_TYPE_EDGE_RISING:\n+\t\tedge = GPIO_RPMSG_TRI_RISING;\n+\t\tirq_set_handler_locked(d, handle_simple_irq);\n+\t\tbreak;\n+\tcase IRQ_TYPE_EDGE_FALLING:\n+\t\tedge = GPIO_RPMSG_TRI_FALLING;\n+\t\tirq_set_handler_locked(d, handle_simple_irq);\n+\t\tbreak;\n+\tcase IRQ_TYPE_EDGE_BOTH:\n+\t\tedge = GPIO_RPMSG_TRI_BOTH_EDGE;\n+\t\tirq_set_handler_locked(d, handle_simple_irq);\n+\t\tbreak;\n+\tcase IRQ_TYPE_LEVEL_LOW:\n+\t\tedge = GPIO_RPMSG_TRI_LOW_LEVEL;\n+\t\tirq_set_handler_locked(d, handle_level_irq);\n+\t\tbreak;\n+\tcase IRQ_TYPE_LEVEL_HIGH:\n+\t\tedge = GPIO_RPMSG_TRI_HIGH_LEVEL;\n+\t\tirq_set_handler_locked(d, handle_level_irq);\n+\t\tbreak;\n+\tdefault:\n+\t\tret = -EINVAL;\n+\t\tirq_set_handler_locked(d, handle_bad_irq);\n+\t\tbreak;\n+\t}\n+\n+\tport->gpio_pins[gpio_idx].irq_type = edge;\n+\n+\treturn ret;\n+}\n+\n+static int gpio_rpmsg_irq_set_wake(struct irq_data *d, u32 enable)\n+{\n+\tstruct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);\n+\tu32 gpio_idx = d->hwirq;\n+\n+\tport->gpio_pins[gpio_idx].irq_wake_enable = enable;\n+\n+\treturn 0;\n+}\n+\n+/*\n+ * This unmask/mask function is invoked in two situations:\n+ *   - when an interrupt is being set up, and\n+ *   - after an interrupt has occurred.\n+ *\n+ * The GPIO driver does not access hardware registers directly.\n+ * Instead, it caches all relevant information locally, and then sends\n+ * the accumulated state to the remote system at this stage.\n+ */\n+static void gpio_rpmsg_unmask_irq(struct irq_data *d)\n+{\n+\tstruct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);\n+\tu32 gpio_idx = d->hwirq;\n+\n+\tport->gpio_pins[gpio_idx].irq_unmask = 1;\n+}\n+\n+static void gpio_rpmsg_mask_irq(struct irq_data *d)\n+{\n+\tstruct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);\n+\tu32 gpio_idx = d->hwirq;\n+\n+\t/*\n+\t * When an interrupt occurs, the remote system masks the interrupt\n+\t * and then sends a notification to Linux. After Linux processes\n+\t * that notification, it sends an RPMsg command back to the remote\n+\t * system to unmask the interrupt again.\n+\t */\n+\tport->gpio_pins[gpio_idx].irq_mask = 1;\n+}\n+\n+static void gpio_rpmsg_irq_shutdown(struct irq_data *d)\n+{\n+\tstruct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);\n+\tu32 gpio_idx = d->hwirq;\n+\n+\tport->gpio_pins[gpio_idx].irq_shutdown = 1;\n+}\n+\n+static void gpio_rpmsg_irq_bus_lock(struct irq_data *d)\n+{\n+\tstruct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);\n+\n+\tmutex_lock(&port->info.lock);\n+}\n+\n+static void gpio_rpmsg_irq_bus_sync_unlock(struct irq_data *d)\n+{\n+\tstruct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);\n+\tstruct gpio_rpmsg_packet *msg = NULL;\n+\tu32 gpio_idx = d->hwirq;\n+\n+\t/*\n+\t * For mask irq, do nothing here.\n+\t * The remote system will mask interrupt after an interrupt occurs,\n+\t * and then send a notify to Linux system.\n+\t * After Linux system dealt with the notify, it will send an rpmsg to\n+\t * the remote system to unmask this interrupt again.\n+\t */\n+\tif (port->gpio_pins[gpio_idx].irq_mask && !port->gpio_pins[gpio_idx].irq_unmask) {\n+\t\tport->gpio_pins[gpio_idx].irq_mask = 0;\n+\t\tmutex_unlock(&port->info.lock);\n+\t\treturn;\n+\t}\n+\n+\tmsg = gpio_setup_msg_header(port, gpio_idx, GPIO_RPMSG_INPUT_INIT);\n+\n+\tif (port->gpio_pins[gpio_idx].irq_shutdown) {\n+\t\tmsg->out.event = GPIO_RPMSG_TRI_IGNORE;\n+\t\tmsg->in.wakeup = 0;\n+\t\tport->gpio_pins[gpio_idx].irq_shutdown = 0;\n+\t} else {\n+\t\t/* if not set irq type, then use low level as trigger type */\n+\t\tmsg->out.event = port->gpio_pins[gpio_idx].irq_type;\n+\t\tif (!msg->out.event)\n+\t\t\tmsg->out.event = GPIO_RPMSG_TRI_LOW_LEVEL;\n+\t\tif (port->gpio_pins[gpio_idx].irq_unmask) {\n+\t\t\tmsg->in.wakeup = 0;\n+\t\t\tport->gpio_pins[gpio_idx].irq_unmask = 0;\n+\t\t} else /* irq set wake */\n+\t\t\tmsg->in.wakeup = port->gpio_pins[gpio_idx].irq_wake_enable;\n+\t}\n+\n+\tgpio_send_message(port, msg, false);\n+\tmutex_unlock(&port->info.lock);\n+}\n+\n+static const struct irq_chip gpio_rpmsg_irq_chip = {\n+\t.irq_mask = gpio_rpmsg_mask_irq,\n+\t.irq_unmask = gpio_rpmsg_unmask_irq,\n+\t.irq_set_wake = gpio_rpmsg_irq_set_wake,\n+\t.irq_set_type = gpio_rpmsg_irq_set_type,\n+\t.irq_shutdown = gpio_rpmsg_irq_shutdown,\n+\t.irq_bus_lock = gpio_rpmsg_irq_bus_lock,\n+\t.irq_bus_sync_unlock = gpio_rpmsg_irq_bus_sync_unlock,\n+\t.flags = IRQCHIP_IMMUTABLE,\n+};\n+\n+static void rpmsg_gpio_remove_action(void *data)\n+{\n+\tstruct rpmsg_gpio_port *port = data;\n+\n+\tport->info.port_store[port->idx] = NULL;\n+}\n+\n+static int rpmsg_gpiochip_register(struct rpmsg_device *rpdev, struct device_node *np)\n+{\n+\tstruct rpdev_drvdata *drvdata = dev_get_drvdata(&rpdev->dev);\n+\tstruct rpmsg_gpio_port *port;\n+\tstruct gpio_irq_chip *girq;\n+\tstruct gpio_chip *gc;\n+\tint ret;\n+\n+\tport = devm_kzalloc(&rpdev->dev, sizeof(*port), GFP_KERNEL);\n+\tif (!port)\n+\t\treturn -ENOMEM;\n+\n+\tret = of_property_read_u32(np, \"reg\", &port->idx);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tif (port->idx >= MAX_PORT_PER_CHANNEL)\n+\t\treturn -EINVAL;\n+\n+\tret = devm_mutex_init(&rpdev->dev, &port->info.lock);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tinit_completion(&port->info.cmd_complete);\n+\tport->info.reply_msg = devm_kzalloc(&rpdev->dev,\n+\t\t\t\t\t    sizeof(struct gpio_rpmsg_packet),\n+\t\t\t\t\t    GFP_KERNEL);\n+\tport->info.port_store = drvdata->channel_devices;\n+\tport->info.port_store[port->idx] = port;\n+\tport->info.rpdev = rpdev;\n+\n+\tgc = &port->gc;\n+\tgc->owner = THIS_MODULE;\n+\tgc->parent = &rpdev->dev;\n+\tgc->fwnode = of_fwnode_handle(np);\n+\tgc->ngpio = GPIOS_PER_PORT;\n+\tgc->base = -1;\n+\tgc->label = devm_kasprintf(&rpdev->dev, GFP_KERNEL, \"%s-gpio%d\",\n+\t\t\t\t   drvdata->rproc_name, port->idx);\n+\n+\tgc->direction_input = rpmsg_gpio_direction_input;\n+\tgc->direction_output = rpmsg_gpio_direction_output;\n+\tgc->get_direction = rpmsg_gpio_get_direction;\n+\tgc->get = rpmsg_gpio_get;\n+\tgc->set = rpmsg_gpio_set;\n+\n+\tgirq = &gc->irq;\n+\tgpio_irq_chip_set_chip(girq, &gpio_rpmsg_irq_chip);\n+\tgirq->parent_handler = NULL;\n+\tgirq->num_parents = 0;\n+\tgirq->parents = NULL;\n+\tgirq->chip->name = devm_kasprintf(&rpdev->dev, GFP_KERNEL, \"%s-gpio%d\",\n+\t\t\t\t\t  drvdata->rproc_name, port->idx);\n+\n+\tret = devm_add_action_or_reset(&rpdev->dev, rpmsg_gpio_remove_action, port);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\treturn devm_gpiochip_add_data(&rpdev->dev, gc, port);\n+}\n+\n+static const char *rpmsg_get_rproc_node_name(struct rpmsg_device *rpdev)\n+{\n+\tconst char *name = NULL;\n+\tstruct device_node *np;\n+\tstruct rproc *rproc;\n+\n+\trproc = rproc_get_by_child(&rpdev->dev);\n+\n+\tif (!rproc)\n+\t\treturn NULL;\n+\n+\tnp = of_node_get(rproc->dev.of_node);\n+\tif (!np && rproc->dev.parent)\n+\t\tnp = of_node_get(rproc->dev.parent->of_node);\n+\n+\tif (np) {\n+\t\tname = devm_kstrdup(&rpdev->dev, np->name, GFP_KERNEL);\n+\t\tof_node_put(np);\n+\t}\n+\n+\treturn name;\n+}\n+\n+static struct device_node *\n+rpmsg_get_channel_ofnode(struct rpmsg_device *rpdev, char *chan_name)\n+{\n+\tstruct device_node *np_chan = NULL, *np;\n+\tstruct rproc *rproc;\n+\n+\trproc = rproc_get_by_child(&rpdev->dev);\n+\tif (!rproc)\n+\t\treturn NULL;\n+\n+\tnp = of_node_get(rproc->dev.of_node);\n+\tif (!np && rproc->dev.parent)\n+\t\tnp = of_node_get(rproc->dev.parent->of_node);\n+\n+\tif (np) {\n+\t\t/* Balance the of_node_put() performed by of_find_node_by_name(). */\n+\t\tof_node_get(np);\n+\t\tnp_chan = of_find_node_by_name(np, chan_name);\n+\t\tof_node_put(np);\n+\t}\n+\n+\treturn np_chan;\n+}\n+\n+static int\n+rpmsg_gpio_channel_callback(struct rpmsg_device *rpdev, void *data,\n+\t\t\t    int len, void *priv, u32 src)\n+{\n+\tstruct gpio_rpmsg_packet *msg = data;\n+\tstruct rpmsg_gpio_port *port = NULL;\n+\tstruct rpdev_drvdata *drvdata;\n+\n+\tdrvdata = dev_get_drvdata(&rpdev->dev);\n+\tif (drvdata && msg && (msg->port_idx < MAX_PORT_PER_CHANNEL))\n+\t\tport = drvdata->channel_devices[msg->port_idx];\n+\n+\tif (!port)\n+\t\treturn -ENODEV;\n+\n+\tif (msg->header.type == GPIO_RPMSG_REPLY) {\n+\t\t*port->info.reply_msg = *msg;\n+\t\tcomplete(&port->info.cmd_complete);\n+\t} else if (msg->header.type == GPIO_RPMSG_NOTIFY) {\n+\t\tgeneric_handle_domain_irq_safe(port->gc.irq.domain, msg->pin_idx);\n+\t} else\n+\t\tdev_err(&rpdev->dev, \"wrong command type!\\n\");\n+\n+\treturn 0;\n+}\n+\n+static int rpmsg_gpio_channel_probe(struct rpmsg_device *rpdev)\n+{\n+\tstruct device *dev = &rpdev->dev;\n+\tstruct rpdev_drvdata *drvdata;\n+\tstruct device_node *np;\n+\tint ret;\n+\n+\tif (!dev->of_node) {\n+\t\tnp = rpmsg_get_channel_ofnode(rpdev, rpdev->id.name);\n+\t\tif (np) {\n+\t\t\tdev->of_node = np;\n+\t\t\tset_primary_fwnode(dev, of_fwnode_handle(np));\n+\t\t}\n+\t\treturn -EPROBE_DEFER;\n+\t}\n+\n+\tdrvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);\n+\tif (!drvdata)\n+\t\treturn -ENOMEM;\n+\n+\tdrvdata->rproc_name = rpmsg_get_rproc_node_name(rpdev);\n+\tdev_set_drvdata(dev, drvdata);\n+\n+\tfor_each_child_of_node_scoped(dev->of_node, child) {\n+\t\tif (!of_device_is_available(child))\n+\t\t\tcontinue;\n+\n+\t\tif (!of_match_node(dev->driver->of_match_table, child))\n+\t\t\tcontinue;\n+\n+\t\tret = rpmsg_gpiochip_register(rpdev, child);\n+\t\tif (ret < 0)\n+\t\t\tdev_err(dev, \"Failed to register: %pOF\\n\", child);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void rpmsg_gpio_channel_remove(struct rpmsg_device *rpdev)\n+{\n+\tdev_info(&rpdev->dev, \"rpmsg gpio channel driver is removed\\n\");\n+}\n+\n+static const struct of_device_id rpmsg_gpio_dt_ids[] = {\n+\t{ .compatible = \"rpmsg-gpio\" },\n+\t{ /* sentinel */ }\n+};\n+\n+static struct rpmsg_device_id rpmsg_gpio_channel_id_table[] = {\n+\t{ .name\t= \"rpmsg-io-channel\" },\n+\t{ },\n+};\n+MODULE_DEVICE_TABLE(rpmsg, rpmsg_gpio_channel_id_table);\n+\n+static struct rpmsg_driver rpmsg_gpio_channel_client = {\n+\t.drv.name\t= KBUILD_MODNAME,\n+\t.drv.of_match_table = rpmsg_gpio_dt_ids,\n+\t.id_table\t= rpmsg_gpio_channel_id_table,\n+\t.probe\t\t= rpmsg_gpio_channel_probe,\n+\t.callback\t= rpmsg_gpio_channel_callback,\n+\t.remove\t\t= rpmsg_gpio_channel_remove,\n+};\n+module_rpmsg_driver(rpmsg_gpio_channel_client);\n+\n+MODULE_AUTHOR(\"Shenwei Wang <shenwei.wang@nxp.com>\");\n+MODULE_DESCRIPTION(\"generic rpmsg gpio driver\");\n+MODULE_LICENSE(\"GPL\");\n",
    "prefixes": [
        "v7",
        "3/4"
    ]
}