Received: by 10.223.148.5 with SMTP id 5csp6336236wrq; Wed, 17 Jan 2018 12:23:47 -0800 (PST) X-Google-Smtp-Source: ACJfBothmBOl6TA3ASIjSt5zy20SUQzd5d1Z4+Awg66M4993kO+S6oMB7X0r3JOf19RavtmJ191V X-Received: by 10.98.245.214 with SMTP id b83mr29575713pfm.85.1516220627416; Wed, 17 Jan 2018 12:23:47 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516220627; cv=none; d=google.com; s=arc-20160816; b=XYFijXyxKo2hXWrd/RPwIQroF8PU1gcsmwv+LPYd8eMftswhGMzrdiOJbcrKQlBdHo sk0ySNg9yXh1GNKY8UilgMP4xPKEuL67U3OUNupSX/+Y/uroaqeImm4CzSKkxw0KtKwH /AoNVBdvv9WRZfloCdgltEDgJKd4iszebW7NUwDn03cdUj2sq0rsp9JRSAiKh5eluO8g Lsynexz7euPu14RUQ/nMgsS4V3KAY081QcCewqFBLbvwV8pfFDvcNtsY5ODTeJfGrM9u O8UX4Pu+Il7aKNQyvIE2WZvrEplQezuVGonOlKavvdgzrCnATLe00Zb4eMV0BR4MV1ds ymSA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:spamdiagnosticmetadata :spamdiagnosticoutput:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=h1s0u1h8AyH6Y8fQJz9Qbe8uMIjDMv04CmjCviASii4=; b=wnhlAQKO6suhfKRgPJTJTx+oF0yNenypIQjOtEwGnOWn/S+sRlADfgUPsDIstaNP26 RdREJtFQ2awPM3mJ4ElizKGT7hzq9H8dw8awaTV4vYOobSxjG/9dkvsznfPlyBsdRc4o GsPowDnSndIhk6P2IzvGYErvljQ6VKBZOc0GWTAyeAEzC/SzL6xNptDQ1EjBkPLEZ8Ge HVZVueQ0hyVFxm0kkp9goQiFGircllAw4LoXe60ZBMs+XbH5xvYuBY+2B1/AtWoN/GGN OI0NTnAr5KIa3F9W4OA1IRoTnVgYLidoic5AilVAZJTqS1bvUKnuKzPDsPs3sdIL4J5W Zeuw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@xilinx.onmicrosoft.com header.s=selector1-xilinx-com header.b=WsVkdd0n; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a89si5066716pla.153.2018.01.17.12.23.33; Wed, 17 Jan 2018 12:23:47 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@xilinx.onmicrosoft.com header.s=selector1-xilinx-com header.b=WsVkdd0n; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753209AbeAQUVm (ORCPT + 99 others); Wed, 17 Jan 2018 15:21:42 -0500 Received: from mail-by2nam01on0048.outbound.protection.outlook.com ([104.47.34.48]:46496 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752925AbeAQUVQ (ORCPT ); Wed, 17 Jan 2018 15:21:16 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=xilinx.onmicrosoft.com; s=selector1-xilinx-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=h1s0u1h8AyH6Y8fQJz9Qbe8uMIjDMv04CmjCviASii4=; b=WsVkdd0n7O+5y9Csg42YZy4qFXQlLf7e4asdL1nPsMzAuxJXtwoRpgZ3L3GfInlmQVpn9FF5l2SlJ7sM0xs/KcXUYVZAEnLQLUy2scmZp1rkPBGUpuy0ciw1lAfJIldzcpJJhkoi/Oa+276iHaQsP731NVf+hIgmDcEatxrLId8= Received: from SN4PR0201CA0028.namprd02.prod.outlook.com (10.162.76.14) by BY2PR02MB1332.namprd02.prod.outlook.com (10.162.79.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.407.7; Wed, 17 Jan 2018 20:21:10 +0000 Received: from CY1NAM02FT024.eop-nam02.prod.protection.outlook.com (2a01:111:f400:7e45::202) by SN4PR0201CA0028.outlook.office365.com (2603:10b6:803:2e::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.407.7 via Frontend Transport; Wed, 17 Jan 2018 20:21:10 +0000 Authentication-Results: spf=pass (sender IP is 149.199.60.83) smtp.mailfrom=xilinx.com; vger.kernel.org; dkim=none (message not signed) header.d=none;vger.kernel.org; dmarc=bestguesspass action=none header.from=xilinx.com; Received-SPF: Pass (protection.outlook.com: domain of xilinx.com designates 149.199.60.83 as permitted sender) receiver=protection.outlook.com; client-ip=149.199.60.83; helo=xsj-pvapsmtpgw01; Received: from xsj-pvapsmtpgw01 (149.199.60.83) by CY1NAM02FT024.mail.protection.outlook.com (10.152.74.210) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.20.428.12 via Frontend Transport; Wed, 17 Jan 2018 20:21:09 +0000 Received: from unknown-38-66.xilinx.com ([149.199.38.66] helo=xsj-pvapsmtp01) by xsj-pvapsmtpgw01 with esmtp (Exim 4.63) (envelope-from ) id 1ebuCq-00034G-Em; Wed, 17 Jan 2018 12:21:08 -0800 Received: from [127.0.0.1] (helo=localhost) by xsj-pvapsmtp01 with smtp (Exim 4.63) (envelope-from ) id 1ebuCq-0000qz-HC; Wed, 17 Jan 2018 12:21:08 -0800 Received: from xsj-pvapsmtp01 (smtp.xilinx.com [149.199.38.66]) by xsj-smtp-dlp1.xlnx.xilinx.com (8.13.8/8.13.1) with ESMTP id w0HKKtjS017769; Wed, 17 Jan 2018 12:20:55 -0800 Received: from [172.19.2.91] (helo=xsjjollys50.xilinx.com) by xsj-pvapsmtp01 with esmtp (Exim 4.63) (envelope-from ) id 1ebuCd-0000nS-5z; Wed, 17 Jan 2018 12:20:55 -0800 From: Jolly Shah To: , , , , , , , , , , CC: , , , , Jolly Shah Subject: [PATCH v2 4/4] drivers: firmware: xilinx: Add debugfs interface Date: Wed, 17 Jan 2018 12:20:34 -0800 Message-ID: <1516220434-22204-5-git-send-email-jollys@xilinx.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1516220434-22204-1-git-send-email-jollys@xilinx.com> References: <1516220434-22204-1-git-send-email-jollys@xilinx.com> X-RCIS-Action: ALLOW X-TM-AS-Product-Ver: IMSS-7.1.0.1224-8.2.0.1013-23600.005 X-TM-AS-User-Approved-Sender: Yes;Yes X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-HT: Tenant X-Forefront-Antispam-Report: CIP:149.199.60.83;IPV:NLI;CTRY:US;EFV:NLI;SFV:NSPM;SFS:(10009020)(39860400002)(39380400002)(376002)(396003)(346002)(2980300002)(438002)(189003)(199004)(288314003)(2201001)(72206003)(305945005)(36386004)(50226002)(6666003)(8676002)(81166006)(5660300001)(575784001)(2950100002)(63266004)(8936002)(316002)(77096007)(36756003)(8746002)(81156014)(2906002)(9786002)(48376002)(107886003)(110136005)(59450400001)(7416002)(51416003)(4326008)(47776003)(478600001)(356003)(106466001)(106002)(54906003)(7696005)(50466002)(5890100001)(76176011)(39060400002)(26005)(107986001)(921003)(1121003);DIR:OUT;SFP:1101;SCL:1;SRVR:BY2PR02MB1332;H:xsj-pvapsmtpgw01;FPR:;SPF:Pass;PTR:unknown-60-83.xilinx.com;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;CY1NAM02FT024;1:9flbErTHW5mGHqWllRDNO8gIX1m7jNu5NnLAnkj1FRqbIBXkjpzgLA3tMfa4dXp1HegAxdkz3FxZLoiqTYlqSdQsGmPHJSCpDSdCTTVfPvf1qE/9gm4UkdT2onkZXe0E MIME-Version: 1.0 Content-Type: text/plain X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 60c52702-7275-475e-9c88-08d55de7d90f X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(7020095)(4652020)(5600026)(4604075)(4608076)(2017052603307)(7153060);SRVR:BY2PR02MB1332; X-Microsoft-Exchange-Diagnostics: 1;BY2PR02MB1332;3:TL7wwFfQxkNrQQ0BDZe0KlfHHM7PeXRqQQ5mULikYbN+E30C7WfquF3wkRpe3Lfrj6qRFlP4e6UU9NSYHYWALQEx1b8hnCejKgRE9N50eEHStMhhExIE40irh0UDDm8fvHNAwzXKOxl5mQ/26ZuVLbhouA4cSNfQWSpr0D8wJLur7KN/OFK2CcMAf4wfBB1VPjKEdorvM951LB1+yeM/Br7WkSQq+bt6sJ5wXyYN3ZunbHKh1U+8U4hEp/BoF/nr4H/f55z8dW8E+8M+iu+S9Acaj7mBslH/eOfP4UyS9l3Wb7wRkB4MGyey7kL3MKDreTZTxf6Erexo4B/6ItGxV/PbwOGW5+BrEzuzIjR96ls=;25:066Wwm1LLNsu2hvOCPgFDTa58tTCYfms8Mb0Re1v0DXOPMt1InclbEbdRAhJhrMHPJjDKIO2airD/OpAMr3JPWUHDgMf8l/XnlH1n0wqgZ9h81aLMiGkX61vj+V/ATLuRkOHMMYow/Qa1iCZIx3OvjmlWuP2+pP8P9Q2aWFJ1cTcxKQ/xT7LTlAFHWmYWQ8kZDM8DfdIA0iHnLVS9/fqtEw8TSMpjNwpTHQU5nQkP6o/1oSD4jWMsz9Uh5MBNjW2PJTuOTx9WzaxwlicxWYCM87OYSijlT/o0/5TF+e0ITT/anRdTzbkmZ+5F+mgFcvoXUSH6sUbgnp4LdaVPp8mJA== X-MS-TrafficTypeDiagnostic: BY2PR02MB1332: X-Microsoft-Exchange-Diagnostics: 1;BY2PR02MB1332;31:f2Z5mvXjT8Jou8H7gl+/fYBwLi7DhUHdfJvUTl7WUHwjjhShdSDq6TfqZoSnKhmVPzPA7fG295XL0CWNYnnTF11k0+iqV2cZgyv2513a+jukTnxUZCGklCbbJQ6gzRMeg1inEAPvv3S2EOwpnsYsprrXywguP0WVA4p1AJH526XX8l2q7YDnst51NqeHmsb7SwOjDWRr9BoEUkLL5S+YjtGJpn6BZBJ2gs0buyc4bDI=;20:txL2+jE86WqCClBffyBxY95qYeStfG9N6dfOSgNNhassvgZeKnwGBY4PwRjpQ9jn+y3LJsbOMYb4ZXp7Yh2lsVDo+nh3TH0CP9DYf+/XqQm35bGjCrVNDugUBXmwcPVJynA9StXu40UgJs55uAY3KlhVFPEnruNq5dsQZ3PgLH9n59Gccei443kK+T4S1qHAX6ciqhav5gxXMna6/P5MSyUgJnsGZ+W9QgpzKahYxrsDHm5okxGXgLCm0kjpigNCAYwEkDdLaDECJ+gqSeC8GtXh8GNHU7Kc0Uzxgc505xRUaa5Q3YpYmO6njoCE4rnlcLqsNOoeRyKTtpDF3SC7UYGCSKw79e7wWmdYKWZmwuH8E2HT9B+IqQ5MgLC60nteQDh3W+aIr3Gowpvlj9t5wOzari0by7XLj37U8hscx9c3bhiT5DjiZ3p8buVutKE36kccgOLLTDUs0jviW0Ry6oOA49hPQIHZnwqtlrvx7NwLMF2xp5IQg+nIHlWHz6G+ Content-Transfer-Encoding: quoted-printable X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(192813158149592); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040470)(2401047)(5005006)(8121501046)(3231023)(2400048)(944501161)(10201501046)(3002001)(93006095)(93004095)(6055026)(6041268)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(20161123558120)(20161123564045)(20161123560045)(6072148)(201708071742011);SRVR:BY2PR02MB1332;BCL:0;PCL:0;RULEID:(100000803101)(100110400095);SRVR:BY2PR02MB1332; X-Microsoft-Exchange-Diagnostics: 1;BY2PR02MB1332;4:4MNCoEUnl5Whc1KUFarzidJmnN+OfeTC+7HQTaptct/7YBmnLGZy/7WJDVQJai7s21YXFgZ1pDwoEdPbg1gCksWNLg9/iKdfgQkZIOs0tIKG9iukUs9paOcbwEdmWzTUXpdaFdI5qRn6zcULMs6y98vaLNmNTM7rYqlZ1oEKKTVceJ2B3aWxTWn9tGxAtJoSHTWbTc4E6yaHzsXWo44H+ffUTmzX5aELxevwLwkjaNKqwGms32yJhka72tjMAgAPn1aMRUXz/AmwSIlZXTHuuhz5s1uJBffX+0lb5RLEWchWDKY9G5vO5gGuxTBdrScP X-Forefront-PRVS: 0555EC8317 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BY2PR02MB1332;23:jwApTMBx53Dc7JlqaBTUbuY3PEAmVstLQHY0jMiKd?= =?us-ascii?Q?9oieeEQ0fQuOcvKoD6gyubbdthvFcpiQAgLvbAPTe6jNY2gjyxUrhQvRGodf?= =?us-ascii?Q?ZZcQ1wdDBZY9diFTknBQoKkRHzyw3THZWpN1zooPdPZqO8jya5dCm0sElew7?= =?us-ascii?Q?YQNnA+jV9XtWp/F6vDagHgk1Joi4ckT895gwqVOadm9YGn9kxVXON+w33hMz?= =?us-ascii?Q?oFzwI1tfTu5DExt5hD01ffjFbbxRNd7BNGPfDMsJRo7ANCmLWJpRiK5DAt8v?= =?us-ascii?Q?wyOnu/Yf+Pu9uRYclxVxpYqWp6kxNlXSjky1h/cB2E4RrHtqbQVUDPp6RKx1?= =?us-ascii?Q?LfOZtFt2yPPPfYZjpXdZ3ycaFMJkcX8Ppz/7rDBAxbfqdOpAzjO6ev7n9wrG?= =?us-ascii?Q?N4rD9+pXZ6NiQNWb+C6ndWrd3eQoLfpLL79Wp+3jMYL0SriwqWMN0f43+qLo?= =?us-ascii?Q?QQgARfl4HBS5qhEeFblgC2Tc9/EPgZaF3RkNRrpTW9moB/z+Bq3BY2H/oWcl?= =?us-ascii?Q?Kf9J/YRuDQ8FZTicknQRHwWGU+ORMVv1nZIOwDBsjye6OI+TOCxN7zqNjnQN?= =?us-ascii?Q?XNMehBqgK39CIkWCdl1kMqsYI6kFLcbbhibSG/DmDg/rEN/v/Diie3IKfbJr?= =?us-ascii?Q?hcjPtDmMMVw9BAMK+gIEJEH/sZfwpTJ4e/AIui+u0/4R0zoDuFDng8AKyvAy?= =?us-ascii?Q?sfJ8daI5CNZF3wza1fCL/m6aLWhraXk4GM5mBcCcbQOaSmvaO0d/vb9EAMYw?= =?us-ascii?Q?5zPa9fbU/jneeZvOchsSxUKzHDEudLUTFpLbfjH/d7b96wL+/t/2lF0ej9pe?= =?us-ascii?Q?B4iKJRcKoN9P5QxB9riUZoN42RHDITjh+2YRpiqDO/BKm/haWaQFCqDAsCqG?= =?us-ascii?Q?NLlKLgsK+e6fU8a0Y3e+Wofhac0K7QcTlatSp8meZ5pKWJltMe/uWH1FModx?= =?us-ascii?Q?t+gp2oXBI3XMVjuWZTJjabcsPSYRlWOzdiybRwQJpn4l8j7H57LRO6TszTBK?= =?us-ascii?Q?HWGmzaw17il5sJLJ+T0cWAf7htux2xWiUhdDHFTkpECGZyzRkQOBKCB4dJwH?= =?us-ascii?Q?FavFx1gb5HJ02ErnlwgfUX3+75cJcSjVdMjsXnc0pgK+YpQztqeYdctrh52x?= =?us-ascii?Q?UC+8VzdqQtuXRMaIEWLe3478TWPq9QGRlT/kIS1CONMAjag8lKIrFa3Fd48F?= =?us-ascii?Q?k1oJtY9AHVqJeoVkKOtYPYUXm+qKsCsiOVb?= X-Microsoft-Exchange-Diagnostics: 1;BY2PR02MB1332;6:S/D4OnPgWaY3tdXhiK4ivgr4Ryrvn0Eb64RpB2jAqonMlIDRs2JN0Q1snCYoEN5wrPyP+AxDbvSiBYKZ1AWcXeOWC1IDH4qnMSQrUSnyg8EYg3OVnxJ3bQZUsyvFQohWtHvYh/yRBOdtysLHgAqAsFZ/2SoJWIGMyLlG2mCE9SMvKiLkjSMwRfWxE2bTxbTJtco54u6W5iKyhZLrBV3AlIbRQJsPAkNHtkUH2S5mOIUfqv4QuJrauS+diLgbOmzjeAcMHXf4SxUPhIsByt3uX0YucWQLbSF3l0zdLjEPlwfN00FzbKbgjuXnoCdrGGyw2KeEyZdYJRmvLhg5EXC6hARdxT6QP3yYJAl+2Y1qLFE=;5:KM++igzFPAP6m6vs1UeKpnBkAM03qsBHFzM6o6lj4Bb2qgjW/Wuwslbhv6LfGUJgpypUv8JlY4J6nVfmj3K9OhqgV9j6O0tnKryICrrZIQ3PoqPhJ9m0eGneXHT+aKQcuxv8ZwKHh3dBH7dTd3xEVkinTrj3HUdKysU5G4lcmLA=;24:vfK/9d5b2xa243kFetIJDzFW36ipz24f0bNgbIuvjqxi7MTYDKkRpuP+JA7+IIshSuMw+BIVMHoYbN4CNfnTGkBYmhJcIqquNwIXRCV7mME=;7:7/QPszoELRVwPLTe40e5Z2v7gSzll9dIC5skC1A/dtxVzM5bMZP/dKsVJqDdHgFjHiDHSDM/ZXj3EA2xRdBF63RcC4i5RGEVqlWaovFe8F1K1YPpmjNhJj05rxVsJ3vbpw6x+AH35nqntqwrhPhd/EGfRN8Q+RpLACPZD71jJu8vlgDqUp0Go1fWt0cHCCcAxSdRU/m+eBqQExg8rRrBv/9Oo8S1NisVKGiHgmsUJLH18zllLruZ5IBAKMLStfTo SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: xilinx.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jan 2018 20:21:09.2362 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 60c52702-7275-475e-9c88-08d55de7d90f X-MS-Exchange-CrossTenant-Id: 657af505-d5df-48d0-8300-c31994686c5c X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=657af505-d5df-48d0-8300-c31994686c5c;Ip=[149.199.60.83];Helo=[xsj-pvapsmtpgw01] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY2PR02MB1332 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Firmware-debug provides debugfs interface to all APIs. Signed-off-by: Jolly Shah Signed-off-by: Rajan Vaja --- drivers/firmware/xilinx/zynqmp/Kconfig | 7 + drivers/firmware/xilinx/zynqmp/Makefile | 1 + drivers/firmware/xilinx/zynqmp/firmware-debug.c | 524 +++++++++++++++++= ++++ drivers/firmware/xilinx/zynqmp/firmware.c | 11 +- .../linux/firmware/xilinx/zynqmp/firmware-debug.h | 31 ++ 5 files changed, 573 insertions(+), 1 deletion(-) create mode 100644 drivers/firmware/xilinx/zynqmp/firmware-debug.c create mode 100644 include/linux/firmware/xilinx/zynqmp/firmware-debug.h diff --git a/drivers/firmware/xilinx/zynqmp/Kconfig b/drivers/firmware/xili= nx/zynqmp/Kconfig index 8f7709d..bdd0188 100644 --- a/drivers/firmware/xilinx/zynqmp/Kconfig +++ b/drivers/firmware/xilinx/zynqmp/Kconfig @@ -13,4 +13,11 @@ config ZYNQMP_FIRMWARE Say yes to enable zynqmp firmware interface driver. In doubt, say N +config ZYNQMP_FIRMWARE_DEBUG + bool "Enable Xilinx Zynq MPSoC firmware debug APIs" + default ARCH_ZYNQMP && ZYNQMP_FIRMWARE && DEBUG_FS + help + Say yes to enable zynqmp firmware interface debug APIs. + In doubt, say N + endmenu diff --git a/drivers/firmware/xilinx/zynqmp/Makefile b/drivers/firmware/xil= inx/zynqmp/Makefile index 6629781..02f0c9a 100644 --- a/drivers/firmware/xilinx/zynqmp/Makefile +++ b/drivers/firmware/xilinx/zynqmp/Makefile @@ -2,3 +2,4 @@ # Makefile for Xilinx firmwares obj-$(CONFIG_ZYNQMP_FIRMWARE) +=3D firmware.o firmware-ggs.o +obj-$(CONFIG_ZYNQMP_FIRMWARE_DEBUG) +=3D firmware-debug.o diff --git a/drivers/firmware/xilinx/zynqmp/firmware-debug.c b/drivers/firm= ware/xilinx/zynqmp/firmware-debug.c new file mode 100644 index 0000000..7a9308d --- /dev/null +++ b/drivers/firmware/xilinx/zynqmp/firmware-debug.c @@ -0,0 +1,524 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Xilinx Zynq MPSoC Firmware layer for debugfs APIs + * + * Copyright (C) 2014-2018 Xilinx, Inc. + * + * Michal Simek + * Davorin Mista + * Jolly Shah + * Rajan Vaja + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "zynqmp-firmware" + +#define PM_API_NAME_LEN 50 +#define MAX_API_VERSION_RESP_LEN 50 + +struct pm_api_info { + u32 api_id; + char api_name[PM_API_NAME_LEN]; + char api_name_len; +}; + +#define PM_API(id) {id, #id, strlen(#id)} +static struct pm_api_info pm_api_list[] =3D { + PM_API(PM_REQUEST_SUSPEND), + PM_API(PM_SELF_SUSPEND), + PM_API(PM_FORCE_POWERDOWN), + PM_API(PM_ABORT_SUSPEND), + PM_API(PM_REQUEST_WAKEUP), + PM_API(PM_SET_WAKEUP_SOURCE), + PM_API(PM_SYSTEM_SHUTDOWN), + PM_API(PM_REQUEST_NODE), + PM_API(PM_RELEASE_NODE), + PM_API(PM_SET_REQUIREMENT), + PM_API(PM_SET_MAX_LATENCY), + PM_API(PM_GET_API_VERSION), + PM_API(PM_SET_CONFIGURATION), + PM_API(PM_GET_NODE_STATUS), + PM_API(PM_GET_OPERATING_CHARACTERISTIC), + PM_API(PM_REGISTER_NOTIFIER), + PM_API(PM_RESET_ASSERT), + PM_API(PM_RESET_GET_STATUS), + PM_API(PM_MMIO_READ), + PM_API(PM_MMIO_WRITE), + PM_API(PM_GET_CHIPID), + PM_API(PM_PINCTRL_GET_FUNCTION), + PM_API(PM_PINCTRL_SET_FUNCTION), + PM_API(PM_PINCTRL_CONFIG_PARAM_GET), + PM_API(PM_PINCTRL_CONFIG_PARAM_SET), + PM_API(PM_IOCTL), + PM_API(PM_CLOCK_ENABLE), + PM_API(PM_CLOCK_DISABLE), + PM_API(PM_CLOCK_GETSTATE), + PM_API(PM_CLOCK_SETDIVIDER), + PM_API(PM_CLOCK_GETDIVIDER), + PM_API(PM_CLOCK_SETRATE), + PM_API(PM_CLOCK_GETRATE), + PM_API(PM_CLOCK_SETPARENT), + PM_API(PM_CLOCK_GETPARENT), + PM_API(PM_QUERY_DATA), +}; + +/** + * zynqmp_pm_self_suspend - PM call for master to suspend itself + * @node: Node ID of the master or subsystem + * @latency: Requested maximum wakeup latency (not supported) + * @state: Requested state (not supported) + * + * Return: Returns status, either success or error+reason + */ +int zynqmp_pm_self_suspend(const u32 node, + const u32 latency, + const u32 state) +{ + return invoke_pm_fn(PM_SELF_SUSPEND, node, latency, state, 0, NULL)= ; +} + +/** + * zynqmp_pm_abort_suspend - PM call to announce that a prior suspend requ= est + * is to be aborted. + * @reason: Reason for the abort + * + * Return: Returns status, either success or error+reason + */ +int zynqmp_pm_abort_suspend(const enum zynqmp_pm_abort_reason reason) +{ + return invoke_pm_fn(PM_ABORT_SUSPEND, reason, 0, 0, 0, NULL); +} + +/** + * zynqmp_pm_register_notifier - Register the PU to be notified of PM even= ts + * @node: Node ID of the slave + * @event: The event to be notified about + * @wake: Wake up on event + * @enable: Enable or disable the notifier + * + * Return: Returns status, either success or error+reason + */ +int zynqmp_pm_register_notifier(const u32 node, const u32 event, + const u32 wake, const u32 enable) +{ + return invoke_pm_fn(PM_REGISTER_NOTIFIER, node, event, + wake, enable, NULL); +} + +/** + * zynqmp_pm_argument_value - Extract argument value from a PM-API request + * @arg: Entered PM-API argument in string format + * + * Return: Argument value in unsigned integer format on success + * 0 otherwise + */ +static u64 zynqmp_pm_argument_value(char *arg) +{ + u64 value; + + if (!arg) + return 0; + + if (!kstrtou64(arg, 0, &value)) + return value; + + return 0; +} + +static struct dentry *zynqmp_pm_debugfs_dir; +static struct dentry *zynqmp_pm_debugfs_power; +static struct dentry *zynqmp_pm_debugfs_api_version; + +static int get_pm_api_id(char *pm_api_req, u32 *pm_id) +{ + int i; + + for (i =3D 0; i < ARRAY_SIZE(pm_api_list) ; i++) { + if (!strncasecmp(pm_api_req, pm_api_list[i].api_name, + pm_api_list[i].api_name_len)) { + *pm_id =3D pm_api_list[i].api_id; + break; + } + } + + /* If no name was entered look for PM-API ID instead */ + if (i =3D=3D ARRAY_SIZE(pm_api_list) && kstrtouint(pm_api_req, 10, = pm_id)) + return -EINVAL; + + return 0; +} + +static int process_api_request(u32 pm_id, u64 *pm_api_arg, u32 *pm_api_ret= ) +{ + const struct zynqmp_eemi_ops *eemi_ops =3D get_eemi_ops(); + u32 pm_api_version; + int ret; + + if (!eemi_ops) + return -ENXIO; + + switch (pm_id) { + case PM_GET_API_VERSION: + eemi_ops->get_api_version(&pm_api_version); + pr_info("%s PM-API Version =3D %d.%d\n", __func__, + pm_api_version >> 16, pm_api_version & 0xffff); + break; + case PM_REQUEST_SUSPEND: + ret =3D eemi_ops->request_suspend(pm_api_arg[0], + pm_api_arg[1] ? pm_api_arg[= 1] : + ZYNQMP_PM_REQUEST_ACK_NO, + pm_api_arg[2] ? pm_api_arg[= 2] : + ZYNQMP_PM_MAX_LATENCY, 0); + break; + case PM_SELF_SUSPEND: + ret =3D zynqmp_pm_self_suspend(pm_api_arg[0], + pm_api_arg[1] ? pm_api_arg[1] = : + ZYNQMP_PM_MAX_LATENCY, 0); + break; + case PM_FORCE_POWERDOWN: + ret =3D eemi_ops->force_powerdown(pm_api_arg[0], + pm_api_arg[1] ? pm_api_arg[= 1] : + ZYNQMP_PM_REQUEST_ACK_NO); + break; + case PM_ABORT_SUSPEND: + ret =3D zynqmp_pm_abort_suspend(pm_api_arg[0] ? pm_api_arg[= 0] : + ZYNQMP_PM_ABORT_REASON_UNKNOW= N); + break; + case PM_REQUEST_WAKEUP: + ret =3D eemi_ops->request_wakeup(pm_api_arg[0], + pm_api_arg[1], pm_api_arg[2]= , + pm_api_arg[3] ? pm_api_arg[3= ] : + ZYNQMP_PM_REQUEST_ACK_NO); + break; + case PM_SET_WAKEUP_SOURCE: + ret =3D eemi_ops->set_wakeup_source(pm_api_arg[0], pm_api_a= rg[1], + pm_api_arg[2]); + break; + case PM_SYSTEM_SHUTDOWN: + ret =3D eemi_ops->system_shutdown(pm_api_arg[0], pm_api_arg= [1]); + break; + case PM_REQUEST_NODE: + ret =3D eemi_ops->request_node(pm_api_arg[0], + pm_api_arg[1] ? pm_api_arg[1] = : + ZYNQMP_PM_CAPABILITY_ACCESS, + pm_api_arg[2] ? pm_api_arg[2] = : 0, + pm_api_arg[3] ? pm_api_arg[3] = : + ZYNQMP_PM_REQUEST_ACK_BLOCKING= ); + break; + case PM_RELEASE_NODE: + ret =3D eemi_ops->release_node(pm_api_arg[0]); + break; + case PM_SET_REQUIREMENT: + ret =3D eemi_ops->set_requirement(pm_api_arg[0], + pm_api_arg[1] ? pm_api_arg[= 1] : + ZYNQMP_PM_CAPABILITY_CONTEX= T, + pm_api_arg[2] ? + pm_api_arg[2] : 0, + pm_api_arg[3] ? pm_api_arg[= 3] : + ZYNQMP_PM_REQUEST_ACK_BLOCK= ING); + break; + case PM_SET_MAX_LATENCY: + ret =3D eemi_ops->set_max_latency(pm_api_arg[0], + pm_api_arg[1] ? pm_api_arg[= 1] : + ZYNQMP_PM_MAX_LATENCY); + break; + case PM_SET_CONFIGURATION: + ret =3D eemi_ops->set_configuration(pm_api_arg[0]); + break; + case PM_GET_NODE_STATUS: + ret =3D eemi_ops->get_node_status(pm_api_arg[0], + &pm_api_ret[0], + &pm_api_ret[1], + &pm_api_ret[2]); + if (!ret) + pr_info("GET_NODE_STATUS:\n\tNodeId: %llu\n\tStatus= : %u\n\tRequirements: %u\n\tUsage: %u\n", + pm_api_arg[0], pm_api_ret[0], + pm_api_ret[1], pm_api_ret[2]); + break; + case PM_GET_OPERATING_CHARACTERISTIC: + ret =3D eemi_ops->get_operating_characteristic(pm_api_arg[0= ], + pm_api_arg[1] ? pm_api_arg[1] : + ZYNQMP_PM_OPERATING_CHARACTERISTIC_POWER, + &pm_api_ret[0]); + if (!ret) + pr_info("GET_OPERATING_CHARACTERISTIC:\n\tNodeId: %= llu\n\tType: %llu\n\tResult: %u\n", + pm_api_arg[0], pm_api_arg[1], pm_api_ret[0]= ); + break; + case PM_REGISTER_NOTIFIER: + ret =3D zynqmp_pm_register_notifier(pm_api_arg[0], + pm_api_arg[1] ? + pm_api_arg[1] : 0, + pm_api_arg[2] ? + pm_api_arg[2] : 0, + pm_api_arg[3] ? + pm_api_arg[3] : 0); + break; + case PM_RESET_ASSERT: + ret =3D eemi_ops->reset_assert(pm_api_arg[0], pm_api_arg[1]= ); + break; + case PM_RESET_GET_STATUS: + ret =3D eemi_ops->reset_get_status(pm_api_arg[0], &pm_api_r= et[0]); + pr_info("%s Reset status: %u\n", __func__, pm_api_ret[0]); + break; + case PM_GET_CHIPID: + ret =3D eemi_ops->get_chipid(&pm_api_ret[0], &pm_api_ret[1]= ); + pr_info("%s idcode: %#x, version:%#x\n", + __func__, pm_api_ret[0], pm_api_ret[1]); + break; + case PM_PINCTRL_GET_FUNCTION: + ret =3D eemi_ops->pinctrl_get_function(pm_api_arg[0], + &pm_api_ret[0]); + pr_info("%s Current set function for the pin: %u\n", + __func__, pm_api_ret[0]); + break; + case PM_PINCTRL_SET_FUNCTION: + ret =3D eemi_ops->pinctrl_set_function(pm_api_arg[0], + pm_api_arg[1]); + break; + case PM_PINCTRL_CONFIG_PARAM_GET: + ret =3D eemi_ops->pinctrl_get_config(pm_api_arg[0], pm_api_= arg[1], + &pm_api_ret[0]); + pr_info("%s pin: %llu, param: %llu, value: %u\n", + __func__, pm_api_arg[0], pm_api_arg[1], + pm_api_ret[0]); + break; + case PM_PINCTRL_CONFIG_PARAM_SET: + ret =3D eemi_ops->pinctrl_set_config(pm_api_arg[0], + pm_api_arg[1], + pm_api_arg[2]); + break; + case PM_IOCTL: + ret =3D eemi_ops->ioctl(pm_api_arg[0], pm_api_arg[1], + pm_api_arg[2], pm_api_arg[3], + &pm_api_ret[0]); + if (pm_api_arg[1] =3D=3D IOCTL_GET_RPU_OPER_MODE || + pm_api_arg[1] =3D=3D IOCTL_GET_PLL_FRAC_MODE || + pm_api_arg[1] =3D=3D IOCTL_GET_PLL_FRAC_DATA || + pm_api_arg[1] =3D=3D IOCTL_READ_GGS || + pm_api_arg[1] =3D=3D IOCTL_READ_PGGS) + pr_info("%s Value: %u\n", + __func__, pm_api_ret[1]); + break; + case PM_CLOCK_ENABLE: + ret =3D eemi_ops->clock_enable(pm_api_arg[0]); + break; + case PM_CLOCK_DISABLE: + ret =3D eemi_ops->clock_disable(pm_api_arg[0]); + break; + case PM_CLOCK_GETSTATE: + ret =3D eemi_ops->clock_getstate(pm_api_arg[0], &pm_api_ret= [0]); + pr_info("%s state: %u\n", __func__, pm_api_ret[0]); + break; + case PM_CLOCK_SETDIVIDER: + ret =3D eemi_ops->clock_setdivider(pm_api_arg[0], pm_api_ar= g[1]); + break; + case PM_CLOCK_GETDIVIDER: + ret =3D eemi_ops->clock_getdivider(pm_api_arg[0], &pm_api_r= et[0]); + pr_info("%s Divider Value: %d\n", __func__, pm_api_ret[0]); + break; + case PM_CLOCK_SETRATE: + ret =3D eemi_ops->clock_setrate(pm_api_arg[0], pm_api_arg[1= ]); + break; + case PM_CLOCK_GETRATE: + ret =3D eemi_ops->clock_getrate(pm_api_arg[0], &pm_api_ret[= 0]); + pr_info("%s Rate Value: %u\n", __func__, pm_api_ret[0]); + break; + case PM_CLOCK_SETPARENT: + ret =3D eemi_ops->clock_setparent(pm_api_arg[0], pm_api_arg= [1]); + break; + case PM_CLOCK_GETPARENT: + ret =3D eemi_ops->clock_getparent(pm_api_arg[0], &pm_api_re= t[0]); + pr_info("%s Parent Index: %u\n", __func__, pm_api_ret[0]); + break; + case PM_QUERY_DATA: + { + struct zynqmp_pm_query_data qdata =3D {0}; + + qdata.qid =3D pm_api_arg[0]; + qdata.arg1 =3D pm_api_arg[1]; + qdata.arg2 =3D pm_api_arg[2]; + qdata.arg3 =3D pm_api_arg[3]; + + ret =3D eemi_ops->query_data(qdata, pm_api_ret); + + pr_info("%s: data[0] =3D 0x%08x\n", __func__, pm_api_ret[0]= ); + pr_info("%s: data[1] =3D 0x%08x\n", __func__, pm_api_ret[1]= ); + pr_info("%s: data[2] =3D 0x%08x\n", __func__, pm_api_ret[2]= ); + pr_info("%s: data[3] =3D 0x%08x\n", __func__, pm_api_ret[3]= ); + break; + } + default: + pr_err("%s Unsupported PM-API request\n", __func__); + ret =3D -EINVAL; + } + + return ret; +} + +/** + * zynqmp_pm_debugfs_api_write - debugfs write function + * @file: User file structure + * @ptr: User entered PM-API string + * @len: Length of the userspace buffer + * @off: Offset within the file + * + * Return: Number of bytes copied if PM-API request succeeds, + * the corresponding error code otherwise + * + * Used for triggering pm api functions by writing + * echo > /sys/kernel/debug/zynqmp_pm/power or + * echo > /sys/kernel/debug/zynqmp_pm/power + */ +static ssize_t zynqmp_pm_debugfs_api_write(struct file *file, + const char __user *ptr, size_t l= en, + loff_t *off) +{ + char *kern_buff, *tmp_buff; + char *pm_api_req; + u32 pm_id =3D 0; + u64 pm_api_arg[4] =3D {0, 0, 0, 0}; + /* Return values from PM APIs calls */ + u32 pm_api_ret[4] =3D {0, 0, 0, 0}; + + int ret; + int i =3D 0; + + if (*off !=3D 0 || len =3D=3D 0) + return -EINVAL; + + kern_buff =3D memdup_user(ptr, len); + if (IS_ERR(kern_buff)) + return PTR_ERR(kern_buff); + + tmp_buff =3D kern_buff; + + /* Read the API name from a user request */ + pm_api_req =3D strsep(&kern_buff, " "); + + ret =3D get_pm_api_id(pm_api_req, &pm_id); + if (ret < 0) + goto err; + + /* Read node_id and arguments from the PM-API request */ + pm_api_req =3D strsep(&kern_buff, " "); + while ((i < ARRAY_SIZE(pm_api_arg)) && pm_api_req) { + pm_api_arg[i++] =3D zynqmp_pm_argument_value(pm_api_req); + pm_api_req =3D strsep(&kern_buff, " "); + } + + ret =3D process_api_request(pm_id, pm_api_arg, pm_api_ret); + +err: + kfree(tmp_buff); + if (ret) + return ret; + else + return len; +} + +/** + * zynqmp_pm_debugfs_api_version_read - debugfs read function + * @file: User file structure + * @ptr: Requested pm_api_version string + * @len: Length of the userspace buffer + * @off: Offset within the file + * + * Return: Length of the version string on success + * -EFAULT otherwise + * + * Used to display the pm api version. + * cat /sys/kernel/debug/zynqmp_pm/pm_api_version + */ +static ssize_t zynqmp_pm_debugfs_api_version_read(struct file *file, + char __user *ptr, size_t = len, + loff_t *off) +{ + int ret; + u32 pm_api_version; + const struct zynqmp_eemi_ops *eemi_ops =3D get_eemi_ops(); + char resp[MAX_API_VERSION_RESP_LEN]; + u32 resp_len; + + if (!eemi_ops || !eemi_ops->get_api_version) + return -ENXIO; + + if (*off !=3D 0) + return 0; + + eemi_ops->get_api_version(&pm_api_version); + resp_len =3D snprintf(resp, MAX_API_VERSION_RESP_LEN, + "PM-API Version =3D %d.%d\n", + pm_api_version >> 16, + pm_api_version & 0xffff); + + if (len < resp_len) + return -EINVAL; + + ret =3D copy_to_user(ptr, resp, resp_len); + if (ret) + return -EFAULT; + + *off =3D resp_len + 1; + + return resp_len; +} + +/* Setup debugfs fops */ +static const struct file_operations fops_zynqmp_pm_dbgfs =3D { + .owner =3D THIS_MODULE, + .write =3D zynqmp_pm_debugfs_api_write, + .read =3D zynqmp_pm_debugfs_api_version_read, +}; + +/** + * zynqmp_pm_api_debugfs_init - Initialize debugfs interface + * + * Return: Returns 0 on success + * Corresponding error code otherwise + */ +int zynqmp_pm_api_debugfs_init(void) +{ + int err; + + /* Initialize debugfs interface */ + zynqmp_pm_debugfs_dir =3D debugfs_create_dir(DRIVER_NAME, NULL); + if (!zynqmp_pm_debugfs_dir) { + pr_err("debugfs_create_dir failed\n"); + return -ENODEV; + } + + zynqmp_pm_debugfs_power =3D + debugfs_create_file("pm", 0220, + zynqmp_pm_debugfs_dir, NULL, + &fops_zynqmp_pm_dbgfs); + if (!zynqmp_pm_debugfs_power) { + pr_err("debugfs_create_file power failed\n"); + err =3D -ENODEV; + goto err_dbgfs; + } + + zynqmp_pm_debugfs_api_version =3D + debugfs_create_file("api_version", 0444, + zynqmp_pm_debugfs_dir, NULL, + &fops_zynqmp_pm_dbgfs); + if (!zynqmp_pm_debugfs_api_version) { + pr_err("debugfs_create_file api_version failed\n"); + err =3D -ENODEV; + goto err_dbgfs; + } + + return 0; + +err_dbgfs: + debugfs_remove_recursive(zynqmp_pm_debugfs_dir); + zynqmp_pm_debugfs_dir =3D NULL; + + return err; +} diff --git a/drivers/firmware/xilinx/zynqmp/firmware.c b/drivers/firmware/x= ilinx/zynqmp/firmware.c index c42cf9f..5e20e3b 100644 --- a/drivers/firmware/xilinx/zynqmp/firmware.c +++ b/drivers/firmware/xilinx/zynqmp/firmware.c @@ -20,6 +20,7 @@ #include #include +#include #define DRIVER_NAME "zynqmp_firmware" @@ -996,9 +997,17 @@ MODULE_DEVICE_TABLE(of, firmware_of_match); static int zynqmp_firmware_probe(struct platform_device *pdev) { + int ret; + + ret =3D zynqmp_pm_api_debugfs_init(); + if (ret) { + pr_err("%s() debugfs init fail with error %d\n", __func__, = ret); + return ret; + } + zynqmp_pm_ggs_init(&pdev->dev); - return 0; + return ret; } static struct platform_driver zynqmp_firmware_platform_driver =3D { diff --git a/include/linux/firmware/xilinx/zynqmp/firmware-debug.h b/includ= e/linux/firmware/xilinx/zynqmp/firmware-debug.h new file mode 100644 index 0000000..73faa45 --- /dev/null +++ b/include/linux/firmware/xilinx/zynqmp/firmware-debug.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Xilinx Zynq MPSoC Firmware layer + * + * Copyright (C) 2014-2018 Xilinx + * + * Michal Simek + * Davorin Mista + * Jolly Shah + * Rajan Vaja + */ + +#ifndef __SOC_ZYNQMP_FIRMWARE_DEBUG_H__ +#define __SOC_ZYNQMP_FIRMWARE_DEBUG_H__ + +#include + +int zynqmp_pm_self_suspend(const u32 node, + const u32 latency, + const u32 state); +int zynqmp_pm_abort_suspend(const enum zynqmp_pm_abort_reason reason); +int zynqmp_pm_register_notifier(const u32 node, const u32 event, + const u32 wake, const u32 enable); + +#if IS_REACHABLE(CONFIG_DEBUG_FS) +int zynqmp_pm_api_debugfs_init(void); +#else +static inline int zynqmp_pm_api_debugfs_init(void) { return 0; } +#endif + +#endif /* __SOC_ZYNQMP_FIRMWARE_DEBUG_H__ */ -- 2.7.4 This email and any attachments are intended for the sole use of the named r= ecipient(s) and contain(s) confidential information that may be proprietary= , privileged or copyrighted under applicable law. If you are not the intend= ed recipient, do not read, copy, or forward this email message or any attac= hments. Delete this email message and any attachments immediately.