Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2195288/?format=api
{ "id": 2195288, "url": "http://patchwork.ozlabs.org/api/patches/2195288/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-gpio/patch/20260210170439.406513-5-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": "<20260210170439.406513-5-shenwei.wang@nxp.com>", "list_archive_url": null, "date": "2026-02-10T17:04:38", "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/20260210170439.406513-5-shenwei.wang@nxp.com/mbox/", "series": [ { "id": 491711, "url": "http://patchwork.ozlabs.org/api/series/491711/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-gpio/list/?series=491711", "date": "2026-02-10T17:04:34", "name": "Enable Remote GPIO over RPMSG on i.MX Platform", "version": 7, "mbox": "http://patchwork.ozlabs.org/series/491711/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2195288/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2195288/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "\n <linux-gpio+bounces-31562-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=iQP7Mw/B;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=172.234.253.10; helo=sea.lore.kernel.org;\n envelope-from=linux-gpio+bounces-31562-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=\"iQP7Mw/B\"", "smtp.subspace.kernel.org;\n arc=fail smtp.client-ip=40.107.159.15", "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 sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10])\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 4f9ShZ3TjZz1xwG\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 11 Feb 2026 04:09:02 +1100 (AEDT)", "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id CA69D30994A1\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 10 Feb 2026 17:06:02 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 2922B32AAB4;\n\tTue, 10 Feb 2026 17:06:02 +0000 (UTC)", "from OSPPR02CU001.outbound.protection.outlook.com\n (mail-norwayeastazon11013015.outbound.protection.outlook.com [40.107.159.15])\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 D535C3254AC;\n\tTue, 10 Feb 2026 17:05:59 +0000 (UTC)", "from PAXPR04MB9185.eurprd04.prod.outlook.com (2603:10a6:102:231::11)\n by DB9PR04MB8362.eurprd04.prod.outlook.com (2603:10a6:10:241::12) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9587.18; Tue, 10 Feb\n 2026 17:05:54 +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:05:54 +0000" ], "ARC-Seal": [ "i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1770743161; cv=fail;\n b=CD9HNWoCkus8BYQdFt5icfKBS+SjYWmRH8Vr7iXCEtiNQlK7u7qnk4sx6OTYFGOJ5ocjVG7kRzpRhqe4A9bGPOxHOr7/xYS9OVgU411nn3FmUHLFFFJrcx2dcTMAU4HDleElP5/tKxNT5srbLy9g1jzI2K9ci3XKzVq+BkX4OQ0=", "i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;\n b=cFz3FIGd8NV6kJHJEM4qSVUqML2CMS0miTROlXfcV2ajqnLn2hILuhbpXvRIIaBO6H8g9ni+ZoLxj2qPsqmIm0oiIT7ef+5AiWVct3VbU0bOu/09BOtukZgROHnt07hhAJk7UmdrGduT7HBQu5CtcPtDfAPl6OIhF0yA5/W3v0b5A92w4ceiuELdfovCmLFZ4oL8sbbn15UXDAhNoSCqfofWm4DhcvEVDHawFz0QT1OrOmjQcXjZJtZEe9aMpwekifWnPtxX4JOa9U1RXODzg36FUKZUCDhdIGrKrCvRM2oD4XIZWj81LGA5uc/snKgOOmCC5zrDLzzYwHfLzPsr7Q==" ], "ARC-Message-Signature": [ "i=2; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1770743161; 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=gbyiM0jbNtxaUY0KVFv+bWbdCucAL5JbpcG6/3FYOAxj5nNwZ+b1hDKaNloaVNtSrtojKk98p7T/ugXbtRtYZ2RAZAK+Lf9NwxCOZeEycXAVFp4RICPIMm7JTFjKwWED9m4yLUPHxs8FPLMypoyOz5/0WUcryDbMF5ElavaRS30=", "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=UIS+7vH5rY87VXdcDsSKfZmvxwJRwkxUa7HYCMU8VBmNtihYyBj/VFJdGfEneeveyD+CAqvmAg7bRMzOja8sIu89O4fgdMH0P2PSwyIcEdqkfSe/6+xUsnU4pJZXhdI0Z1wX6ulY65328qzAXtPK320a7yCDSt9yanFOYVWxvVUHl4feAKmPNf3K2xiM7ap+UrnLT8zxx5Y/b/ii00lhYzrA+WXVAp5tvBpE2yEF/SXV/zDDMnC4pnnX3tRAy41u+UV7664/+d00jDjQ9rsyqas7ndcgtlZvoNngXGD2up0CU96c2ck4JikqHiX+BJElPUweC+XxB4egtBWtD3JbYA==" ], "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=iQP7Mw/B; arc=fail smtp.client-ip=40.107.159.15", "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=iQP7Mw/BG0TDcS7VUvJYZpVoWspJ7J7Aus0TUNAdR/mqCzNsmF0lTG4UeIUi5Kv+PTnbA+tAkRN7Ck6eButclnGwwBVxVpo94zy67JJjWreGTu3oD78llKlbeoUGwpoCPe8yhQ8vGdbZvkyZXetZprbxWFA0tXepmzjgOENgrc2QXjK/fBYuUTm946tqEwf7O7ne28joUYguRRboGtw7KvUK6dT4w5socG55Tz/LRMMoiPbfTxJMJlFcffo2HuGw18O/dzllyrt6uyfGlNvhW+MMpgn5oalakNI2h+1bZuBK9IHIIol06CKDB2NRnYPz7D++aD9KOniJ2EH3h6B59g==", "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:04:38 -0600", "Message-ID": "<20260210170439.406513-5-shenwei.wang@nxp.com>", "X-Mailer": "git-send-email 2.43.0", "In-Reply-To": "<20260210170439.406513-1-shenwei.wang@nxp.com>", "References": "<20260210170439.406513-1-shenwei.wang@nxp.com>", "Content-Transfer-Encoding": "8bit", "Content-Type": "text/plain", "X-ClientProxiedBy": "PH7P220CA0092.NAMP220.PROD.OUTLOOK.COM\n (2603:10b6:510:32d::28) 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_|DB9PR04MB8362:EE_", "X-MS-Office365-Filtering-Correlation-Id": "004994a5-c3e2-4dfb-a5f2-08de68c6a6d1", "X-MS-Exchange-SenderADCheck": "1", "X-MS-Exchange-AntiSpam-Relay": "0", "X-Microsoft-Antispam": "\n\tBCL:0;ARA:13230040|366016|19092799006|52116014|7416014|376014|1800799024|921020|38350700014;", "X-Microsoft-Antispam-Message-Info": "\n Pt/LcEeVXPEZ/2i75qorhhrIMOnMDNcjlfpcOajv/Q9Cp4NBwvDtSqOm/147XD25/ZJetDr46B/wyfvEG5itnvhEsp+DxuiRusq1fnK70X92Ouwq9qeHgLU7098u41hLumB3yUcsFJEPZf0cZqo0z7KfYi1LKHWVng+sNmOugwNtEvirkXPt/y6RP9fveNQcxqDGPiKrybDxnpfoapd5u4u8/urCvaStQ3IlPMrNKZDaqg/vy0d6Mb/T8R6GioS2NmaCkKd+HcRmdy5ORqrSRPlu2WvKVE9S7KKhO/zpfztSn/No+rVxOVRhq3cOVJ3+Gliv3W43SPJ0pcDbLSR0zNE/XVQ0ZnM0rbdKj/vhKJa0FWGDbuTZ2Xc/69qHimenhdlo9HRnvR1VcTIcBvOYAEB/pCD2BIseYOmC/KkXDt/6CPL73MjMc0m84krjZQo77nRN28amDHChYgyqqinni80YlbDliWkjrIu+lP/jJNLDLn7php020JhifsnzVFE1vxVOPEDQYQyWy3ZoBnkboonmA9nGT3bRHlLJvVsAO2UBbshrEuXUZV4c5crjJbV8TcXAgR0tmeMl9aK200OPSBOSpm1MplEtKfpC2PGN0YnG/orXEMSdFhIOhadF3m33IdMjvkCC5bNBRF7MxStWvz6VNjAExKN1TG3onUA679A1kqu/TkB0YKK3zo7M2EAyRvgCzLd3w/lFm8WKLDrpS1kRkkLHPSFl/RzvjkgdQ2SeKTH9AXZRW5W3drsdTOjknoowuzEeQtJMV8rbQKYny5/1mEp+Y141Rkr6PGwb6W1RsG9fYOrLdSSzGyW4JRV4/7NookQgWHVZWVH70yjA1oOySNZTikwwmMZNAENHtFBB90+o8ny7mr322S6CdESsVP6G3ASkDh/LrNw8qR+AuzGrowGJe4Z8vKcOFE7yQWjLuDe7FhK3OZ7DOj+cJtkT/JDrQWK6Bp5aPn9pwyzVfCVXV+I3qSzm0JQuyMtZbPMGC90jdVzTU0SyFIa6m36KM7Xhk61zGgCx0C4mcOdWRHtHZEIwEdG8txiQ7QSFSVAd7goNVa3FCa9/aUMZmMnw4oFrffFSUxu5ieLb3LqfqbMv1cHlkr/ugXpkSnUEeGygU/AZgd1g9x+xMNJkU6MMjLxVxKoewFk52s7ofJnJ1PEcnKA9zLFbrRl+6fGeg5lNmLxuAKZULlYEUimZ82na45Lcfyf1Dc6iv6qSXiuAZ3lx5W7VqvsCoAvYLCXjCCneKuEO39CbclG/KbacYJmWGiOQVeQz/x8NuBulaeO5NdW3e78fLlFP0WZMB0qYHbZXR9xx3HS+zAeyOUgnP51I9fZunZ24zi+UzbU24IkJa9rgCcNGHM9mKX5g1Nf6ILOe/n2RREAfCWvTkE7YPxlyWrcuCBW8y2jK0XgOQb0+mxaTmGpNvLRiCX/k7URlqRVohjRqOTUWnrvv0XmBWKcjjr3wIkGvWkkTtydC1xowlIjr+RFy+EC4juTXIIuz3Vin1tuFfVWua2JKS1/DaYH5I2YPeaIBdC5EjhHwtfo30ByxfMlWKx4fhuP9quM/MbnUSbTlSsNTOWoraGRWh5LSKutDvAQMSHJrbqyFPOVShMSfUfNdzTk+kiOqjin395R202UsWSREDK4KN+MRYjmt", "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)(366016)(19092799006)(52116014)(7416014)(376014)(1800799024)(921020)(38350700014);DIR:OUT;SFP:1101;", "X-MS-Exchange-AntiSpam-MessageData-ChunkCount": "1", "X-MS-Exchange-AntiSpam-MessageData-0": "\n leuVC8nfHzbkB0RO7QM/gKoe4/McIm9xVQPlR+ZiAyx+mBhASpcSfX64eMpdjHiAbSLDUmr/rndSfMWT0UXzrqfUxmleEFJk/cFj+uSrvfYp0F2aud3IFX7TPMJwJpF2gcb0zyEgAlPABqwtfC+TfeTANT5fYVh+4OpxZkkO1Y7IDwHqraLyQLw0EPRg2OXMdpmyQBLFoLLLFpQKlYtVMuofOp6cSQhVVo2oEv87e4mKbiz7gEAydi85M7/a1SOWv73IeQtLBB6VvZGWCrN5oLFcAIJikUVAZHueFqvgx8JglIXQLuinKHLQrs/KgUA/4L2FwzmN9J/T66sbECvPScc4NDIL/NbxTSvsmS3tOJX0eOa8edYQowydMBOE65wKJRHNrZnYPw2cH52VtXBx+pJA8v2gW2ufkilC5SeHEWTxQkI+50KulfdFQ+lWZswux5y5PtUq4cDtqZ474brguIMZtShkC93ZBPdqM5uChmiU+AONlHXDLE/Ys2fBfUIOhsI/UkyY3PGaOVEnMd0myWN01whNiItxpqfUcU7QAAFY7doweVxz48mrOzW8eBgfcZGHKHKnC9pEDo7S96Dbqni478v2874onvYXoegRGONdrOAtc0T4tpOhiBDRyN2gIyZMOa+bXl+2d3Q8YBnlGUrsIQMhR7XGxnRpfTnTmr3QFXqfAKeJ/vPEXcWdxbWwkhcftgsyBgVOuc4PKComfttOzghD98G2SvkqrdEhPLlYDVl7wOQ28xI7+WsyTp5vkx12sZilcazw28pw16QHYgVLbEdcPqC0p92t4jG6NBjUlQPopH4RZACYWbA163or/qYNf5VsGs9sz0FG9X9+Cd+2i/njlu18W1Gb/6aP2FLX3v0eDMoxQw6bdQcBx9yUBQ1lBSqNJqzjBC1Kvne31ak3+JwGqp95sNzYw5+y/g/tMERxgvn8WdV8WW3i91geQGAiay0Dob7ip1hyX3yNcIdADI5b72uPnyuZ9/Ub0HwUCO3BTznCeDzJxdD8pyp0CGUfjjxst5Jhe3lsMZm6hsV7JrFBAVfM+Ayzjvkb3R6oDXCkMy/28cFzhAlU0do+ZW1zmUr1cFFt1p0z2M2J9fh3jVC/hJkd5yZHC+l/9LEq4qiQ2Ur62qJFF0jh398ssgwKe9aE2KJwcOlNqF5kATde/AtGm7s+22z4KT7YhVikUN5+ByjSaftoVgUGo1BpqgqvheiUH/lNcCkFljM4IG0r/NaNTy+MfkhJfsh5jlKQqC0tAzihW7UDOjwjeDnbmFpUEH79bIhlfATVBOZ9C68NE0W3ikMmc4hRpidmXpFtKTyWlPITInpKMo+C8EhbpqiDyLNfWlNQqri2tC0Xp15zscB8KyVMX0Vms0w8vJ/Eaw4CCm2NItiQ3Gnhs1JHumNtW2+pCek/PWuXAqyu/uGNb/X3ce+3vwkyduxrCISaaMl9QbkrNbvP0lSn4bvN3Qo4tikDP/RxMt6yRWGzVFF+lGlZR3Wb37lks7wFiaDpXTaV1S3HdLBURiDfincCbEYwlS5+2M3M4vlkjfKNRlT1/LzP3m9BJcU0Geyu0j1OrTqW8QfCxyEfuEto2uYxgaBws2nHknBxCw4g9h1ZUpKb+SUxZvMT9uvg5pW5GiIi8h8YzjYAR94CZRYucPanxF9KhCCSWX5Z0eOhA9HvFsmMnw4GlZNSuJgNpNG+cEo2c1lOto1zqNZuNdW/pL2TrIiOPHRPAkECiADkws9RSQ==", "X-OriginatorOrg": "nxp.com", "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 004994a5-c3e2-4dfb-a5f2-08de68c6a6d1", "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:05:54.8244\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 D+0Ee8mdMYyhy/wiCwBl6g6SmoD5tXl3qef6gZDwV7xL0li36U5FKPZubv8+ZqLAyveUiu6PjKvEeyWD2TrRTg==", "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "DB9PR04MB8362" }, "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" ] }