get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2231700,
    "url": "http://patchwork.ozlabs.org/api/1.1/patches/2231700/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linux-tegra/patch/20260501-memory-refactor-v3-1-69fb1ae1a7ca@nvidia.com/",
    "project": {
        "id": 21,
        "url": "http://patchwork.ozlabs.org/api/1.1/projects/21/?format=api",
        "name": "Linux Tegra Development",
        "link_name": "linux-tegra",
        "list_id": "linux-tegra.vger.kernel.org",
        "list_email": "linux-tegra@vger.kernel.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null
    },
    "msgid": "<20260501-memory-refactor-v3-1-69fb1ae1a7ca@nvidia.com>",
    "date": "2026-05-01T07:00:52",
    "name": "[v3] memory: tegra: Deduplicate rate request management code",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "a717d0fe5a2a8d184ea7ac1649d21d4297b1f198",
    "submitter": {
        "id": 26499,
        "url": "http://patchwork.ozlabs.org/api/1.1/people/26499/?format=api",
        "name": "Mikko Perttunen",
        "email": "mperttunen@nvidia.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linux-tegra/patch/20260501-memory-refactor-v3-1-69fb1ae1a7ca@nvidia.com/mbox/",
    "series": [
        {
            "id": 502429,
            "url": "http://patchwork.ozlabs.org/api/1.1/series/502429/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/linux-tegra/list/?series=502429",
            "date": "2026-05-01T07:00:52",
            "name": "[v3] memory: tegra: Deduplicate rate request management code",
            "version": 3,
            "mbox": "http://patchwork.ozlabs.org/series/502429/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2231700/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2231700/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "\n <linux-tegra+bounces-14128-incoming=patchwork.ozlabs.org@vger.kernel.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "linux-tegra@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=Nvidia.com header.i=@Nvidia.com header.a=rsa-sha256\n header.s=selector2 header.b=MAuvcjlX;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c0a:e001:db::12fc:5321; helo=sea.lore.kernel.org;\n envelope-from=linux-tegra+bounces-14128-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)",
            "smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com\n header.b=\"MAuvcjlX\"",
            "smtp.subspace.kernel.org;\n arc=fail smtp.client-ip=40.107.209.25",
            "smtp.subspace.kernel.org;\n dmarc=pass (p=reject dis=none) header.from=nvidia.com",
            "smtp.subspace.kernel.org;\n spf=fail smtp.mailfrom=nvidia.com",
            "dkim=none (message not signed)\n header.d=none;dmarc=none action=none header.from=nvidia.com;"
        ],
        "Received": [
            "from sea.lore.kernel.org (sea.lore.kernel.org\n [IPv6:2600:3c0a:e001:db::12fc:5321])\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 4g6MQL3Kw2z1xqf\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 01 May 2026 17:01:14 +1000 (AEST)",
            "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id 29644300CE57\n\tfor <incoming@patchwork.ozlabs.org>; Fri,  1 May 2026 07:01:12 +0000 (UTC)",
            "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id E98AB31327D;\n\tFri,  1 May 2026 07:01:11 +0000 (UTC)",
            "from PH8PR06CU001.outbound.protection.outlook.com\n (mail-westus3azon11012025.outbound.protection.outlook.com [40.107.209.25])\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 B1A0727442;\n\tFri,  1 May 2026 07:01:09 +0000 (UTC)",
            "from SJ2PR12MB9161.namprd12.prod.outlook.com (2603:10b6:a03:566::20)\n by CY8PR12MB8265.namprd12.prod.outlook.com (2603:10b6:930:72::8) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9870.16; Fri, 1 May\n 2026 07:01:02 +0000",
            "from SJ2PR12MB9161.namprd12.prod.outlook.com\n ([fe80::d9d1:8c49:a703:b017]) by SJ2PR12MB9161.namprd12.prod.outlook.com\n ([fe80::d9d1:8c49:a703:b017%4]) with mapi id 15.20.9870.020; Fri, 1 May 2026\n 07:01:02 +0000"
        ],
        "ARC-Seal": [
            "i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1777618871; cv=fail;\n b=egFqAxPuBO3GbWz8bjGYaEw3IWgjRNtxbqAl29aHP7AGsJRox9H02XjU1I0uDqLoV+IFSizVKbkNsnZh1VZRvE9FWiC9O0X/8wjtyT64ePBDpb/tL160bRtTfnlumwGu3Jbo7FXqE5WlZ2WUNFeIKrs6Ef7lUzeYUnVLJbN8wGI=",
            "i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;\n b=f5/IbWNAeIsDO9qpB38WKu0wgVFRt0rI1weJ2f04XoZy0jWtLIiKeazIzDC+iGTkqEum906Fycuvjry6OLHZcFYPHgnApHmunB0LGDacQWi1MxtB3sbGd79EylSqr7Q+R0Vt94huabjmYf8eoGwnC9MFU3va45vWE3FTPxasWEhvPOE6fjF9qKi2L6mGwW6bikS1t635E3WeYpJEq5ePZrGG/GF6bUMJqolBcgZCfsmjEupHcpICZ0khPaD3nP73LxRqNCeAgj7k01+BHF5iJJ2DdWBTtggGSaNtP9CFQYjNs7i7cXFHT4+Ct+gsT067fXv8QjeowCFEnhx4tOWZcg=="
        ],
        "ARC-Message-Signature": [
            "i=2; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1777618871; c=relaxed/simple;\n\tbh=AG/iranMErqb2tzogpcmrLzxL2Rp0Ud9Lr3qqfie4aY=;\n\th=From:Date:Subject:Content-Type:Message-Id:To:Cc:MIME-Version;\n b=jkXacmFlPxlvHDf6lpbDpLIbhmZr+3FDIA3BVl40lfJk9SvzbWqV1CVRdgYjwmM97yOkzuox0Vj3k+68jxXkBSDiM+rL0uySSpVyVeOH0CxYHtxrtVuRGN27Q70lgsoQxdgDyvyMH5Rg9GVS8AiZUbDDPVpda3EY+w9NtcQnUr8=",
            "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=4ChJMT3YmwaeekzXSUVfq4eDCB40y0wsuiXEE3+p5h4=;\n b=MA3KnAzJhkYvWdjX/s1fz3SeTsDAVHKtKWF3Zqlc/ketWvOcm0tYEsdx5Xh55OcyDNQyqJmni9ZIsCo8qCncQGA4hsjs5O3JNMsz10IMkuNGkt0/6wOzJa6JdjbwHrB6hRReefYKY6B7EAgcla6c7uZhSHn53M34moc8RGvWH+Lr9tuC+tvZdMFq5UfeuhR0BMBCst7MAdyLWsCp8RapKSdRlKJEfKe3SjAUYtZT7FbFa+6slohAEIX/ZRt2weWoF4fTzSkcao8yzVj2pLwNS1RwoF9fXh25JwGRadvaoOVOR/c4hNAkdYTRVSHmb2NQuJprgtfqeA57T24hfTP+Cw=="
        ],
        "ARC-Authentication-Results": [
            "i=2; smtp.subspace.kernel.org;\n dmarc=pass (p=reject dis=none) header.from=nvidia.com;\n spf=fail smtp.mailfrom=nvidia.com;\n dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com\n header.b=MAuvcjlX; arc=fail smtp.client-ip=40.107.209.25",
            "i=1; mx.microsoft.com 1; spf=pass\n smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com;\n dkim=pass header.d=nvidia.com; arc=none"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com;\n s=selector2;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=4ChJMT3YmwaeekzXSUVfq4eDCB40y0wsuiXEE3+p5h4=;\n b=MAuvcjlXk/m4/T+BMXZNv9p/RLIjvRR34vm8GVJ/alF3d/dvdUWZVl2DiD/eqDxMg+shEQI5TlmNOIx59oZquJiwCtSKFGTOKs9Skq4XI12/D/3bZD/YMINB3Uw/N5qUZ47Vy/yhFAJSQeFDVSxvtxaLV4bMP3finoRY9STNmu+4yuWkxKsScTWcIR7UXXDyLZImUz+VeyJd7SWai615gZlWUEsktMRmlhmkuAoLtpGfXThY3GjaGU0toklIf14XRFW5kKT0wQRbftMsfEYgGyRtCdK2n9qXS8eLiCgPwkPRcM6b8L/HxzHersP4uqIAg48b/83aKDLt7ELilK0Pxw==",
        "From": "Mikko Perttunen <mperttunen@nvidia.com>",
        "Date": "Fri, 01 May 2026 16:00:52 +0900",
        "Subject": "[PATCH v3] memory: tegra: Deduplicate rate request management code",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "7bit",
        "Message-Id": "<20260501-memory-refactor-v3-1-69fb1ae1a7ca@nvidia.com>",
        "X-B4-Tracking": "v=1; b=H4sIAAAAAAAC/2WNQQ6CMBREr0L+2prSYimuvIdh0bQf+QuotNhIC\n He3wsKFyzeTmbdCxEAY4VqsEDBRJD9mkKcCbG/GBzJymUFwobjgkg04+LCwgJ2xsw/sUhnFdWO\n 0sx3k1TM39N4f7+3BAadXPp5/YU8xb5fdmsQ3PQRVWf8JkmAlK5VqHEpdN7q7jYkcmbP1A7Tbt\n n0AjCxrFcQAAAA=",
        "X-Change-ID": "20260203-memory-refactor-54a6089a8dcf",
        "To": "Krzysztof Kozlowski <krzk@kernel.org>,\n Thierry Reding <thierry.reding@gmail.com>,\n Jonathan Hunter <jonathanh@nvidia.com>",
        "Cc": "Svyatoslav Ryhel <clamor95@gmail.com>, linux-kernel@vger.kernel.org,\n linux-tegra@vger.kernel.org, Mikko Perttunen <mperttunen@nvidia.com>",
        "X-Mailer": "b4 0.16-dev",
        "X-ClientProxiedBy": "OSAPR01CA0324.jpnprd01.prod.outlook.com\n (2603:1096:604:2a::24) To SJ2PR12MB9161.namprd12.prod.outlook.com\n (2603:10b6:a03:566::20)",
        "Precedence": "bulk",
        "X-Mailing-List": "linux-tegra@vger.kernel.org",
        "List-Id": "<linux-tegra.vger.kernel.org>",
        "List-Subscribe": "<mailto:linux-tegra+subscribe@vger.kernel.org>",
        "List-Unsubscribe": "<mailto:linux-tegra+unsubscribe@vger.kernel.org>",
        "MIME-Version": "1.0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-TrafficTypeDiagnostic": "SJ2PR12MB9161:EE_|CY8PR12MB8265:EE_",
        "X-MS-Office365-Filtering-Correlation-Id": "0f8d2d9b-e6f0-4229-b262-08dea74f6836",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "\n\tBCL:0;ARA:13230040|366016|10070799003|376014|1800799024|18002099003|56012099003;",
        "X-Microsoft-Antispam-Message-Info": "\n\tubfTvONMIORGEpy82yyGOgy2DVx+ZRqVs625o7OelP05RGz2fmfKB4DKIaikB6tAIPlbQkkkxjX8sjBjs907TJ0bUBY5O7+NTFA40DQ9stWRG6SbsOgCWLjj4ZfNoHojHCJcY/5jPMB8ivHkDlBQ940/hsra7VXJ6K0EKf9BmYyDOX7hhWIhbg31zd1Z1vN7oE2Satg9+HA0KLrd5J6D+lO6EgEG331KThbcCCm9SuWyc7VHdlNN3uP3IzvHf8ah16pVLe11btgwBeqZA5DOfDyYx51FRJ7tyeLnjYT62Y/7Dwc7Y5xAJj8YbK0FKWcBCtBeh9EbxyunFC4Z78XVK6U74qMiXvm/Id1HnJw11PfpcnZdBvDwjKaXyEVXp2aP9kI4oQdpvZlkw2brhGmf8UeskqJJQS5iFlCS+hpOrK7gZ648XCAc3aurckAY+WQBectlQc5DAEu3P1tPyW45ZpTHc0/3TRi3rZxpLrgBPZmi8xkLZp3S5OPKKD1kXayae39uJ4VEWLGR9L57M2y8s/uHq+NrtPV4WYR7NwFW4peCSl7jziJFYuxVbMWQT8LmWf9nEG/8GYc3jSwUxZp2eurlWbqxRXgyr2NOJxeInw4iqlFY5wZuSbGWU6gPL0GS3n4oCyCyCGtiPNO4oFBO+ZlkWnd2AYGBinkxqRjsPz+HDSL7D5mr2k9EvnSnmHvL",
        "X-Forefront-Antispam-Report": "\n\tCIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SJ2PR12MB9161.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(10070799003)(376014)(1800799024)(18002099003)(56012099003);DIR:OUT;SFP:1101;",
        "X-MS-Exchange-AntiSpam-MessageData-ChunkCount": "2",
        "X-MS-Exchange-AntiSpam-MessageData-0": "=?utf-8?q?npR4FUwSq0nhOuEO9s33R5o7mpXh?=\n\t=?utf-8?q?XPRealydcgGH1D7Bk4BuNg5AkL6MscGJ+UyEffNckxTcZnctVajUkYQwvGpFQpetQ?=\n\t=?utf-8?q?+fwKsUqjw+f/f6cN1Z/biabvcwh2KpVCO39cslvWNMkrjwCVtuLX+bPiqVI+KC6S5?=\n\t=?utf-8?q?DH3diokV17R2oyAZvHraFn7MZLWKMUA/ScO2kSgX2tGr/bmscwLX8tVfWkuBKfVlb?=\n\t=?utf-8?q?o+gX1v1olAtMbidbSAfaEU7PVT4Wnws2Ug7oTj06c67vWUMGF3ULNlhabZj3O9AkE?=\n\t=?utf-8?q?/LkshZysgj1Rdttbz73enqCxcq5WJq2CG0aogDJHSNh41wBOHiQXLmomjWypZQNR6?=\n\t=?utf-8?q?einQr4xvYymUaLCWmbn4nDlyMPr80Yk0d/b6LKGANq3esnnqTsFbAZTidp/lS9Y8U?=\n\t=?utf-8?q?LqYSJCEQAOmfqrW1sxNFM1D+3TiMGbYOLhzgdO6VQgfEGyO4cuhyGIUirAcs6cpf9?=\n\t=?utf-8?q?L6DIqIRT/jNStK1gBgaaKrvWoacA2l6J03eypUmztGxJxHEsyNZ9MIihjWV9FqSmG?=\n\t=?utf-8?q?mYocH3nlBJmFqPxZBvsdxPzAxLU54tvIpL/FMpnN1xnsatu49J2kDQkQAsWO97Qxs?=\n\t=?utf-8?q?70HT5Inwryt/EjVqwYFytmv6OMh3ifqRxMH8rIIwOKWzvhYdWs8nm4Tnf7EWlfNw1?=\n\t=?utf-8?q?Ap+lI3F6SPLEBI09N9rZUh6wwsItG9AjqFP+Ga8A1TpmfULa1mvlEML/HFC7onMYy?=\n\t=?utf-8?q?+VozfKJls8ZI5YYEVSISkNAU51zmJsb8JPFW8anZjRHMouEEQFhdUUDRXP0cXu3zS?=\n\t=?utf-8?q?wAhxYCkQgiqEea37ETYbZvu+JY4U8IYxVelN8IwdwLhJ5/duBlgIKlnpTHP/9PgZd?=\n\t=?utf-8?q?LGMNdyPDBfyIcOqULAJXnknCCqBhxwSspkyJ5hTXNWbeyEJ+YHWfWL1k5G095Mk5j?=\n\t=?utf-8?q?qGMA0HJpuWkZ2+6N5zypHCYl9djMfJlzj23aWZ6S8GuhdI450XRdnbsybMuZ8ZQ1S?=\n\t=?utf-8?q?Ki7oK2MGu/cUiFptE58ABZjYyljNOcwOjaZeOuWksQWrZV1hWrNccFYQZSLSzbl2t?=\n\t=?utf-8?q?Mylf50ZdACsztZi2ZWpdF/hKlUpSWtVGKhNhHVjG0ZXD4qlMocxdqXDkTUMut5K2Q?=\n\t=?utf-8?q?hvBGQQLdKmfIDseMRdxTQxVofzzKP3Q73jFy81cZgdZEpLOarkcXW1o2j3iMAKUIQ?=\n\t=?utf-8?q?C16QRD/CDs36aVEoKse7u7Xct9ILz2CW7JMdhxXqrTAJlWjT3Yw7JvCLF+JZ3jPnd?=\n\t=?utf-8?q?mbohynig4Ei5iYSszxheQGgEM6spfIpPvpHOvIKrgElenVbs/jkaPO6/Ubg8lDQlV?=\n\t=?utf-8?q?aNGZbkHzNezuBz9OwA4hSfyf36SXiC034EDdOBUP5tEjT9h5lvK+CjApEVlL/sSZX?=\n\t=?utf-8?q?dfLdSoBmyEHCKTuEpB0SJHVH5DWEAlu4DhjOi2WNHbIXCMrB54f5TqnUjz8oUuryW?=\n\t=?utf-8?q?MsDxLEbSEVbn/rsqEEG2GLPgIedqjgcNe1vrheWhWEaXJzOpUhmdqzvq/YqG2gTFZ?=\n\t=?utf-8?q?6ldABQWq3A/vkJXL/eOoh+p8WTW9Mewj0BUu2zxzBmP866kA9hLXcE9s5ghS/oUBc?=\n\t=?utf-8?q?lGv1PjMeikIi8yzRIY9x8U8Nt/EqiXjmhLE7w5j93sbSuchzWJWqzs+8YaP1Y8ZPA?=\n\t=?utf-8?q?z248NSZM5yPCteFlzENSxDONnXswIcQ2T2dI9AjilZRO1wIUJbdgLC3+7olEgBpL2?=\n\t=?utf-8?q?4+UV2/DovjsIyLOhrX1+9Nnnm6ObUIA5DzbQYWaWIlewUfnkSd78pimJFY8kYu+38?=\n\t=?utf-8?q?ER3tA42Q5vJY1/mTV?=",
        "X-MS-Exchange-AntiSpam-MessageData-1": "berRDmPiQDcf+A==",
        "X-OriginatorOrg": "Nvidia.com",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 0f8d2d9b-e6f0-4229-b262-08dea74f6836",
        "X-MS-Exchange-CrossTenant-AuthSource": "SJ2PR12MB9161.namprd12.prod.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Internal",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "01 May 2026 07:01:02.8291\n (UTC)",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "Hosted",
        "X-MS-Exchange-CrossTenant-Id": "43083d15-7273-40c1-b7db-39efd9ccc17a",
        "X-MS-Exchange-CrossTenant-MailboxType": "HOSTED",
        "X-MS-Exchange-CrossTenant-UserPrincipalName": "\n 7dnVCYYTaZdwVFNoYW1lyD5YwxhKwD9Ce6Uk7eMifztTxohcqOg7D2yC4X6wGqE3Vb91vRhQ89sJH12jGEpSCg==",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "CY8PR12MB8265"
    },
    "content": "As is, the EMC drivers for each 32-bit platform contain almost\nidentical duplicated code for aggregating rate requests. Move this\ncode out to a shared tegra-emc-common file to reduce duplication,\nand add kerneldoc comments.\n\nBased on code from the tegra20-emc driver.\n\nSigned-off-by: Mikko Perttunen <mperttunen@nvidia.com>\n---\nChanges in v3:\n- Added comments and lockdep assertion on the rate_lock mutex,\n  addressing checkpatch 'CHECK'.\n- Added module.h include.\n- Link to v2: https://patch.msgid.link/20260417-memory-refactor-v2-1-1669de38798f@nvidia.com\n---\n drivers/memory/tegra/Kconfig            |   6 ++\n drivers/memory/tegra/Makefile           |   1 +\n drivers/memory/tegra/tegra-emc-common.c | 143 ++++++++++++++++++++++++++++++++\n drivers/memory/tegra/tegra-emc-common.h |  46 ++++++++++\n drivers/memory/tegra/tegra124-emc.c     | 107 ++----------------------\n drivers/memory/tegra/tegra20-emc.c      | 110 ++----------------------\n drivers/memory/tegra/tegra30-emc.c      | 107 ++----------------------\n 7 files changed, 215 insertions(+), 305 deletions(-)\n\n\n---\nbase-commit: 028ef9c96e96197026887c0f092424679298aae8\nchange-id: 20260203-memory-refactor-54a6089a8dcf",
    "diff": "diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig\nindex fc5a27791826..92671f9df672 100644\n--- a/drivers/memory/tegra/Kconfig\n+++ b/drivers/memory/tegra/Kconfig\n@@ -17,6 +17,7 @@ config TEGRA20_EMC\n \tselect DEVFREQ_GOV_SIMPLE_ONDEMAND\n \tselect PM_DEVFREQ\n \tselect DDR\n+\tselect TEGRA_EMC_COMMON\n \thelp\n \t  This driver is for the External Memory Controller (EMC) found on\n \t  Tegra20 chips. The EMC controls the external DRAM on the board.\n@@ -29,6 +30,7 @@ config TEGRA30_EMC\n \tdepends on ARCH_TEGRA_3x_SOC || COMPILE_TEST\n \tselect PM_OPP\n \tselect DDR\n+\tselect TEGRA_EMC_COMMON\n \thelp\n \t  This driver is for the External Memory Controller (EMC) found on\n \t  Tegra30 chips. The EMC controls the external DRAM on the board.\n@@ -41,6 +43,7 @@ config TEGRA124_EMC\n \tdepends on ARCH_TEGRA_124_SOC || COMPILE_TEST\n \tselect TEGRA124_CLK_EMC if ARCH_TEGRA\n \tselect PM_OPP\n+\tselect TEGRA_EMC_COMMON\n \thelp\n \t  This driver is for the External Memory Controller (EMC) found on\n \t  Tegra124 chips. The EMC controls the external DRAM on the board.\n@@ -61,4 +64,7 @@ config TEGRA210_EMC\n \t  This driver is required to change memory timings / clock rate for\n \t  external memory.\n \n+config TEGRA_EMC_COMMON\n+\ttristate\n+\n endif\ndiff --git a/drivers/memory/tegra/Makefile b/drivers/memory/tegra/Makefile\nindex 6334601e6120..75ebb4cb4f29 100644\n--- a/drivers/memory/tegra/Makefile\n+++ b/drivers/memory/tegra/Makefile\n@@ -14,6 +14,7 @@ tegra-mc-$(CONFIG_ARCH_TEGRA_264_SOC) += tegra186.o tegra264.o\n \n obj-$(CONFIG_TEGRA_MC) += tegra-mc.o\n \n+obj-$(CONFIG_TEGRA_EMC_COMMON) += tegra-emc-common.o\n obj-$(CONFIG_TEGRA20_EMC)  += tegra20-emc.o\n obj-$(CONFIG_TEGRA30_EMC)  += tegra30-emc.o\n obj-$(CONFIG_TEGRA124_EMC) += tegra124-emc.o\ndiff --git a/drivers/memory/tegra/tegra-emc-common.c b/drivers/memory/tegra/tegra-emc-common.c\nnew file mode 100644\nindex 000000000000..bbe86cb4942c\n--- /dev/null\n+++ b/drivers/memory/tegra/tegra-emc-common.c\n@@ -0,0 +1,143 @@\n+// SPDX-License-Identifier: GPL-2.0\n+\n+#include <linux/device.h>\n+#include <linux/module.h>\n+#include <linux/mutex.h>\n+#include <linux/pm_opp.h>\n+\n+#include \"tegra-emc-common.h\"\n+\n+/**\n+ * tegra_emc_rate_requests_init() - Initialize EMC rate request tracking\n+ * @reqs: struct tegra_emc_rate_requests to initialize.\n+ * @dev: EMC device.\n+ *\n+ * Initializes the rate request tracking state with default state\n+ * (no active requests). Must be called before using @reqs with\n+ * other functions.\n+ */\n+void tegra_emc_rate_requests_init(struct tegra_emc_rate_requests *reqs,\n+\t\t\t\t  struct device *dev)\n+{\n+\tunsigned int i;\n+\n+\tmutex_init(&reqs->rate_lock);\n+\treqs->dev = dev;\n+\n+\tfor (i = 0; i < TEGRA_EMC_RATE_TYPE_MAX; i++) {\n+\t\treqs->requested_rate[i].min_rate = 0;\n+\t\treqs->requested_rate[i].max_rate = ULONG_MAX;\n+\t}\n+}\n+EXPORT_SYMBOL_GPL(tegra_emc_rate_requests_init);\n+\n+/* Caller must hold reqs->rate_lock. */\n+static int tegra_emc_request_rate(struct tegra_emc_rate_requests *reqs,\n+\t\t\t\t  unsigned long new_min_rate,\n+\t\t\t\t  unsigned long new_max_rate,\n+\t\t\t\t  enum tegra_emc_rate_request_type type)\n+{\n+\tstruct tegra_emc_rate_request *req = reqs->requested_rate;\n+\tunsigned long min_rate = 0, max_rate = ULONG_MAX;\n+\tunsigned int i;\n+\tint err;\n+\n+\tlockdep_assert_held(&reqs->rate_lock);\n+\n+\t/* select minimum and maximum rates among the requested rates */\n+\tfor (i = 0; i < TEGRA_EMC_RATE_TYPE_MAX; i++, req++) {\n+\t\tif (i == type) {\n+\t\t\tmin_rate = max(new_min_rate, min_rate);\n+\t\t\tmax_rate = min(new_max_rate, max_rate);\n+\t\t} else {\n+\t\t\tmin_rate = max(req->min_rate, min_rate);\n+\t\t\tmax_rate = min(req->max_rate, max_rate);\n+\t\t}\n+\t}\n+\n+\tif (min_rate > max_rate) {\n+\t\tdev_err_ratelimited(reqs->dev, \"%s: type %u: out of range: %lu %lu\\n\",\n+\t\t\t\t    __func__, type, min_rate, max_rate);\n+\t\treturn -ERANGE;\n+\t}\n+\n+\t/*\n+\t * EMC rate-changes should go via OPP API because it manages voltage\n+\t * changes.\n+\t */\n+\terr = dev_pm_opp_set_rate(reqs->dev, min_rate);\n+\tif (err)\n+\t\treturn err;\n+\n+\treqs->requested_rate[type].min_rate = new_min_rate;\n+\treqs->requested_rate[type].max_rate = new_max_rate;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * tegra_emc_set_min_rate() - Update minimum rate request for a request type\n+ * @reqs: rate request tracking state\n+ * @rate: new minimum rate in Hz requested by @type\n+ * @type: type of request\n+ *\n+ * Records @rate as the new minimum rate request for @type, recalculates target\n+ * rate based on all requests and applies new rate through the OPP API.\n+ *\n+ * Context: Sleeps. Requests to same @reqs are synchronized via mutex.\n+ *\n+ * Return:\n+ * * %0 - success\n+ * * %-ERANGE - request would cause minimum rate request to be higher than\n+ *              maximum rate request\n+ * * other - setting new rate failed\n+ */\n+int tegra_emc_set_min_rate(struct tegra_emc_rate_requests *reqs,\n+\t\t\t   unsigned long rate,\n+\t\t\t   enum tegra_emc_rate_request_type type)\n+{\n+\tstruct tegra_emc_rate_request *req = &reqs->requested_rate[type];\n+\tint ret;\n+\n+\tmutex_lock(&reqs->rate_lock);\n+\tret = tegra_emc_request_rate(reqs, rate, req->max_rate, type);\n+\tmutex_unlock(&reqs->rate_lock);\n+\n+\treturn ret;\n+}\n+EXPORT_SYMBOL_GPL(tegra_emc_set_min_rate);\n+\n+/**\n+ * tegra_emc_set_max_rate() - Update maximum rate request for a request type\n+ * @reqs: rate request tracking state\n+ * @rate: new maximum rate in Hz requested by @type\n+ * @type: type of request\n+ *\n+ * Records @rate as the new maximum rate request for @type, recalculates target\n+ * rate based on all requests and applies new rate through the OPP API.\n+ *\n+ * Context: Sleeps. Requests to same @reqs are synchronized via mutex.\n+ *\n+ * Return:\n+ * * %0 - success\n+ * * %-ERANGE - request would cause minimum rate request to be higher than\n+ *              maximum rate request\n+ * * other - setting new rate failed\n+ */\n+int tegra_emc_set_max_rate(struct tegra_emc_rate_requests *reqs,\n+\t\t\t   unsigned long rate,\n+\t\t\t   enum tegra_emc_rate_request_type type)\n+{\n+\tstruct tegra_emc_rate_request *req = &reqs->requested_rate[type];\n+\tint ret;\n+\n+\tmutex_lock(&reqs->rate_lock);\n+\tret = tegra_emc_request_rate(reqs, req->min_rate, rate, type);\n+\tmutex_unlock(&reqs->rate_lock);\n+\n+\treturn ret;\n+}\n+EXPORT_SYMBOL_GPL(tegra_emc_set_max_rate);\n+\n+MODULE_DESCRIPTION(\"NVIDIA Tegra EMC common code\");\n+MODULE_LICENSE(\"GPL\");\ndiff --git a/drivers/memory/tegra/tegra-emc-common.h b/drivers/memory/tegra/tegra-emc-common.h\nnew file mode 100644\nindex 000000000000..157e27024342\n--- /dev/null\n+++ b/drivers/memory/tegra/tegra-emc-common.h\n@@ -0,0 +1,46 @@\n+/* SPDX-License-Identifier: GPL-2.0 */\n+\n+#ifndef TEGRA_EMC_COMMON_H\n+#define TEGRA_EMC_COMMON_H\n+\n+#include <linux/device.h>\n+#include <linux/mutex.h>\n+\n+/**\n+ * enum tegra_emc_rate_request_type - source of rate request\n+ * @TEGRA_EMC_RATE_DEVFREQ: rate requested by devfreq governor\n+ * @TEGRA_EMC_RATE_DEBUG: rate requested through debugfs knobs\n+ * @TEGRA_EMC_RATE_ICC: rate requested by ICC framework\n+ * @TEGRA_EMC_RATE_TYPE_MAX: number of valid request types\n+ */\n+enum tegra_emc_rate_request_type {\n+\tTEGRA_EMC_RATE_DEVFREQ,\n+\tTEGRA_EMC_RATE_DEBUG,\n+\tTEGRA_EMC_RATE_ICC,\n+\tTEGRA_EMC_RATE_TYPE_MAX,\n+};\n+\n+struct tegra_emc_rate_request {\n+\tunsigned long min_rate;\n+\tunsigned long max_rate;\n+};\n+\n+struct tegra_emc_rate_requests {\n+\tstruct tegra_emc_rate_request requested_rate[TEGRA_EMC_RATE_TYPE_MAX];\n+\t/* Protects @requested_rate. */\n+\tstruct mutex rate_lock;\n+\tstruct device *dev;\n+};\n+\n+void tegra_emc_rate_requests_init(struct tegra_emc_rate_requests *reqs,\n+\t\t\t\t  struct device *dev);\n+\n+int tegra_emc_set_min_rate(struct tegra_emc_rate_requests *reqs,\n+\t\t\t   unsigned long rate,\n+\t\t\t   enum tegra_emc_rate_request_type type);\n+\n+int tegra_emc_set_max_rate(struct tegra_emc_rate_requests *reqs,\n+\t\t\t   unsigned long rate,\n+\t\t\t   enum tegra_emc_rate_request_type type);\n+\n+#endif /* TEGRA_EMC_COMMON_H */\ndiff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c\nindex ff26815e51f1..e33eed6f999e 100644\n--- a/drivers/memory/tegra/tegra124-emc.c\n+++ b/drivers/memory/tegra/tegra124-emc.c\n@@ -27,6 +27,7 @@\n #include <soc/tegra/mc.h>\n \n #include \"mc.h\"\n+#include \"tegra-emc-common.h\"\n \n #define EMC_FBIO_CFG5\t\t\t\t0x104\n #define\tEMC_FBIO_CFG5_DRAM_TYPE_MASK\t\t0x3\n@@ -467,17 +468,6 @@ struct emc_timing {\n \tu32 emc_zcal_interval;\n };\n \n-enum emc_rate_request_type {\n-\tEMC_RATE_DEBUG,\n-\tEMC_RATE_ICC,\n-\tEMC_RATE_TYPE_MAX,\n-};\n-\n-struct emc_rate_request {\n-\tunsigned long min_rate;\n-\tunsigned long max_rate;\n-};\n-\n struct tegra_emc {\n \tstruct device *dev;\n \n@@ -503,14 +493,7 @@ struct tegra_emc {\n \n \tstruct icc_provider provider;\n \n-\t/*\n-\t * There are multiple sources in the EMC driver which could request\n-\t * a min/max clock rate, these rates are contained in this array.\n-\t */\n-\tstruct emc_rate_request requested_rate[EMC_RATE_TYPE_MAX];\n-\n-\t/* protect shared rate-change code path */\n-\tstruct mutex rate_lock;\n+\tstruct tegra_emc_rate_requests reqs;\n };\n \n /* Timing change sequence functions */\n@@ -1041,83 +1024,6 @@ tegra124_emc_find_node_by_ram_code(struct device_node *node, u32 ram_code)\n \treturn NULL;\n }\n \n-static void tegra124_emc_rate_requests_init(struct tegra_emc *emc)\n-{\n-\tunsigned int i;\n-\n-\tfor (i = 0; i < EMC_RATE_TYPE_MAX; i++) {\n-\t\temc->requested_rate[i].min_rate = 0;\n-\t\temc->requested_rate[i].max_rate = ULONG_MAX;\n-\t}\n-}\n-\n-static int emc_request_rate(struct tegra_emc *emc,\n-\t\t\t    unsigned long new_min_rate,\n-\t\t\t    unsigned long new_max_rate,\n-\t\t\t    enum emc_rate_request_type type)\n-{\n-\tstruct emc_rate_request *req = emc->requested_rate;\n-\tunsigned long min_rate = 0, max_rate = ULONG_MAX;\n-\tunsigned int i;\n-\tint err;\n-\n-\t/* select minimum and maximum rates among the requested rates */\n-\tfor (i = 0; i < EMC_RATE_TYPE_MAX; i++, req++) {\n-\t\tif (i == type) {\n-\t\t\tmin_rate = max(new_min_rate, min_rate);\n-\t\t\tmax_rate = min(new_max_rate, max_rate);\n-\t\t} else {\n-\t\t\tmin_rate = max(req->min_rate, min_rate);\n-\t\t\tmax_rate = min(req->max_rate, max_rate);\n-\t\t}\n-\t}\n-\n-\tif (min_rate > max_rate) {\n-\t\tdev_err_ratelimited(emc->dev, \"%s: type %u: out of range: %lu %lu\\n\",\n-\t\t\t\t    __func__, type, min_rate, max_rate);\n-\t\treturn -ERANGE;\n-\t}\n-\n-\t/*\n-\t * EMC rate-changes should go via OPP API because it manages voltage\n-\t * changes.\n-\t */\n-\terr = dev_pm_opp_set_rate(emc->dev, min_rate);\n-\tif (err)\n-\t\treturn err;\n-\n-\temc->requested_rate[type].min_rate = new_min_rate;\n-\temc->requested_rate[type].max_rate = new_max_rate;\n-\n-\treturn 0;\n-}\n-\n-static int emc_set_min_rate(struct tegra_emc *emc, unsigned long rate,\n-\t\t\t    enum emc_rate_request_type type)\n-{\n-\tstruct emc_rate_request *req = &emc->requested_rate[type];\n-\tint ret;\n-\n-\tmutex_lock(&emc->rate_lock);\n-\tret = emc_request_rate(emc, rate, req->max_rate, type);\n-\tmutex_unlock(&emc->rate_lock);\n-\n-\treturn ret;\n-}\n-\n-static int emc_set_max_rate(struct tegra_emc *emc, unsigned long rate,\n-\t\t\t    enum emc_rate_request_type type)\n-{\n-\tstruct emc_rate_request *req = &emc->requested_rate[type];\n-\tint ret;\n-\n-\tmutex_lock(&emc->rate_lock);\n-\tret = emc_request_rate(emc, req->min_rate, rate, type);\n-\tmutex_unlock(&emc->rate_lock);\n-\n-\treturn ret;\n-}\n-\n /*\n  * debugfs interface\n  *\n@@ -1190,7 +1096,7 @@ static int tegra124_emc_debug_min_rate_set(void *data, u64 rate)\n \tif (!tegra124_emc_validate_rate(emc, rate))\n \t\treturn -EINVAL;\n \n-\terr = emc_set_min_rate(emc, rate, EMC_RATE_DEBUG);\n+\terr = tegra_emc_set_min_rate(&emc->reqs, rate, TEGRA_EMC_RATE_DEBUG);\n \tif (err < 0)\n \t\treturn err;\n \n@@ -1220,7 +1126,7 @@ static int tegra124_emc_debug_max_rate_set(void *data, u64 rate)\n \tif (!tegra124_emc_validate_rate(emc, rate))\n \t\treturn -EINVAL;\n \n-\terr = emc_set_max_rate(emc, rate, EMC_RATE_DEBUG);\n+\terr = tegra_emc_set_max_rate(&emc->reqs, rate, TEGRA_EMC_RATE_DEBUG);\n \tif (err < 0)\n \t\treturn err;\n \n@@ -1327,7 +1233,7 @@ static int emc_icc_set(struct icc_node *src, struct icc_node *dst)\n \tdo_div(rate, ddr * dram_data_bus_width_bytes);\n \trate = min_t(u64, rate, U32_MAX);\n \n-\terr = emc_set_min_rate(emc, rate, EMC_RATE_ICC);\n+\terr = tegra_emc_set_min_rate(&emc->reqs, rate, TEGRA_EMC_RATE_ICC);\n \tif (err)\n \t\treturn err;\n \n@@ -1441,7 +1347,6 @@ static int tegra124_emc_probe(struct platform_device *pdev)\n \tif (!emc)\n \t\treturn -ENOMEM;\n \n-\tmutex_init(&emc->rate_lock);\n \temc->dev = &pdev->dev;\n \n \temc->regs = devm_platform_ioremap_resource(pdev, 0);\n@@ -1487,7 +1392,7 @@ static int tegra124_emc_probe(struct platform_device *pdev)\n \tif (err)\n \t\treturn err;\n \n-\ttegra124_emc_rate_requests_init(emc);\n+\ttegra_emc_rate_requests_init(&emc->reqs, &pdev->dev);\n \n \tif (IS_ENABLED(CONFIG_DEBUG_FS))\n \t\temc_debugfs_init(&pdev->dev, emc);\ndiff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c\nindex a1fadefee7fd..1d564b80e2bb 100644\n--- a/drivers/memory/tegra/tegra20-emc.c\n+++ b/drivers/memory/tegra/tegra20-emc.c\n@@ -32,6 +32,7 @@\n #include \"../of_memory.h\"\n \n #include \"mc.h\"\n+#include \"tegra-emc-common.h\"\n \n #define EMC_INTSTATUS\t\t\t\t0x000\n #define EMC_INTMASK\t\t\t\t0x004\n@@ -182,18 +183,6 @@ struct emc_timing {\n \tu32 data[ARRAY_SIZE(emc_timing_registers)];\n };\n \n-enum emc_rate_request_type {\n-\tEMC_RATE_DEVFREQ,\n-\tEMC_RATE_DEBUG,\n-\tEMC_RATE_ICC,\n-\tEMC_RATE_TYPE_MAX,\n-};\n-\n-struct emc_rate_request {\n-\tunsigned long min_rate;\n-\tunsigned long max_rate;\n-};\n-\n struct tegra_emc {\n \tstruct device *dev;\n \tstruct tegra_mc *mc;\n@@ -212,14 +201,7 @@ struct tegra_emc {\n \t\tunsigned long max_rate;\n \t} debugfs;\n \n-\t/*\n-\t * There are multiple sources in the EMC driver which could request\n-\t * a min/max clock rate, these rates are contained in this array.\n-\t */\n-\tstruct emc_rate_request requested_rate[EMC_RATE_TYPE_MAX];\n-\n-\t/* protect shared rate-change code path */\n-\tstruct mutex rate_lock;\n+\tstruct tegra_emc_rate_requests reqs;\n \n \tstruct devfreq_simple_ondemand_data ondemand_data;\n \n@@ -710,83 +692,6 @@ static long emc_round_rate(unsigned long rate,\n \treturn timing->rate;\n }\n \n-static void tegra20_emc_rate_requests_init(struct tegra_emc *emc)\n-{\n-\tunsigned int i;\n-\n-\tfor (i = 0; i < EMC_RATE_TYPE_MAX; i++) {\n-\t\temc->requested_rate[i].min_rate = 0;\n-\t\temc->requested_rate[i].max_rate = ULONG_MAX;\n-\t}\n-}\n-\n-static int emc_request_rate(struct tegra_emc *emc,\n-\t\t\t    unsigned long new_min_rate,\n-\t\t\t    unsigned long new_max_rate,\n-\t\t\t    enum emc_rate_request_type type)\n-{\n-\tstruct emc_rate_request *req = emc->requested_rate;\n-\tunsigned long min_rate = 0, max_rate = ULONG_MAX;\n-\tunsigned int i;\n-\tint err;\n-\n-\t/* select minimum and maximum rates among the requested rates */\n-\tfor (i = 0; i < EMC_RATE_TYPE_MAX; i++, req++) {\n-\t\tif (i == type) {\n-\t\t\tmin_rate = max(new_min_rate, min_rate);\n-\t\t\tmax_rate = min(new_max_rate, max_rate);\n-\t\t} else {\n-\t\t\tmin_rate = max(req->min_rate, min_rate);\n-\t\t\tmax_rate = min(req->max_rate, max_rate);\n-\t\t}\n-\t}\n-\n-\tif (min_rate > max_rate) {\n-\t\tdev_err_ratelimited(emc->dev, \"%s: type %u: out of range: %lu %lu\\n\",\n-\t\t\t\t    __func__, type, min_rate, max_rate);\n-\t\treturn -ERANGE;\n-\t}\n-\n-\t/*\n-\t * EMC rate-changes should go via OPP API because it manages voltage\n-\t * changes.\n-\t */\n-\terr = dev_pm_opp_set_rate(emc->dev, min_rate);\n-\tif (err)\n-\t\treturn err;\n-\n-\temc->requested_rate[type].min_rate = new_min_rate;\n-\temc->requested_rate[type].max_rate = new_max_rate;\n-\n-\treturn 0;\n-}\n-\n-static int emc_set_min_rate(struct tegra_emc *emc, unsigned long rate,\n-\t\t\t    enum emc_rate_request_type type)\n-{\n-\tstruct emc_rate_request *req = &emc->requested_rate[type];\n-\tint ret;\n-\n-\tmutex_lock(&emc->rate_lock);\n-\tret = emc_request_rate(emc, rate, req->max_rate, type);\n-\tmutex_unlock(&emc->rate_lock);\n-\n-\treturn ret;\n-}\n-\n-static int emc_set_max_rate(struct tegra_emc *emc, unsigned long rate,\n-\t\t\t    enum emc_rate_request_type type)\n-{\n-\tstruct emc_rate_request *req = &emc->requested_rate[type];\n-\tint ret;\n-\n-\tmutex_lock(&emc->rate_lock);\n-\tret = emc_request_rate(emc, req->min_rate, rate, type);\n-\tmutex_unlock(&emc->rate_lock);\n-\n-\treturn ret;\n-}\n-\n /*\n  * debugfs interface\n  *\n@@ -857,7 +762,7 @@ static int tegra20_emc_debug_min_rate_set(void *data, u64 rate)\n \tif (!tegra20_emc_validate_rate(emc, rate))\n \t\treturn -EINVAL;\n \n-\terr = emc_set_min_rate(emc, rate, EMC_RATE_DEBUG);\n+\terr = tegra_emc_set_min_rate(&emc->reqs, rate, TEGRA_EMC_RATE_DEBUG);\n \tif (err < 0)\n \t\treturn err;\n \n@@ -887,7 +792,7 @@ static int tegra20_emc_debug_max_rate_set(void *data, u64 rate)\n \tif (!tegra20_emc_validate_rate(emc, rate))\n \t\treturn -EINVAL;\n \n-\terr = emc_set_max_rate(emc, rate, EMC_RATE_DEBUG);\n+\terr = tegra_emc_set_max_rate(&emc->reqs, rate, TEGRA_EMC_RATE_DEBUG);\n \tif (err < 0)\n \t\treturn err;\n \n@@ -993,7 +898,7 @@ static int emc_icc_set(struct icc_node *src, struct icc_node *dst)\n \tdo_div(rate, dram_data_bus_width_bytes);\n \trate = min_t(u64, rate, U32_MAX);\n \n-\terr = emc_set_min_rate(emc, rate, EMC_RATE_ICC);\n+\terr = tegra_emc_set_min_rate(&emc->reqs, rate, TEGRA_EMC_RATE_ICC);\n \tif (err)\n \t\treturn err;\n \n@@ -1111,7 +1016,7 @@ static int tegra20_emc_devfreq_target(struct device *dev, unsigned long *freq,\n \trate = dev_pm_opp_get_freq(opp);\n \tdev_pm_opp_put(opp);\n \n-\treturn emc_set_min_rate(emc, rate, EMC_RATE_DEVFREQ);\n+\treturn tegra_emc_set_min_rate(&emc->reqs, rate, TEGRA_EMC_RATE_DEVFREQ);\n }\n \n static int tegra20_emc_devfreq_get_dev_status(struct device *dev,\n@@ -1190,7 +1095,6 @@ static int tegra20_emc_probe(struct platform_device *pdev)\n \tif (!emc)\n \t\treturn -ENOMEM;\n \n-\tmutex_init(&emc->rate_lock);\n \temc->clk_nb.notifier_call = tegra20_emc_clk_change_notify;\n \temc->dev = &pdev->dev;\n \n@@ -1228,7 +1132,7 @@ static int tegra20_emc_probe(struct platform_device *pdev)\n \t\treturn err;\n \n \tplatform_set_drvdata(pdev, emc);\n-\ttegra20_emc_rate_requests_init(emc);\n+\ttegra_emc_rate_requests_init(&emc->reqs, &pdev->dev);\n \ttegra20_emc_debugfs_init(emc);\n \ttegra20_emc_interconnect_init(emc);\n \ttegra20_emc_devfreq_init(emc);\ndiff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c\nindex 606106dd2b32..afd272da0d27 100644\n--- a/drivers/memory/tegra/tegra30-emc.c\n+++ b/drivers/memory/tegra/tegra30-emc.c\n@@ -36,6 +36,7 @@\n #include \"../of_memory.h\"\n \n #include \"mc.h\"\n+#include \"tegra-emc-common.h\"\n \n #define EMC_INTSTATUS\t\t\t\t0x000\n #define EMC_INTMASK\t\t\t\t0x004\n@@ -341,17 +342,6 @@ struct emc_timing {\n \tbool emc_cfg_dyn_self_ref;\n };\n \n-enum emc_rate_request_type {\n-\tEMC_RATE_DEBUG,\n-\tEMC_RATE_ICC,\n-\tEMC_RATE_TYPE_MAX,\n-};\n-\n-struct emc_rate_request {\n-\tunsigned long min_rate;\n-\tunsigned long max_rate;\n-};\n-\n struct tegra_emc {\n \tstruct device *dev;\n \tstruct tegra_mc *mc;\n@@ -383,14 +373,7 @@ struct tegra_emc {\n \t\tunsigned long max_rate;\n \t} debugfs;\n \n-\t/*\n-\t * There are multiple sources in the EMC driver which could request\n-\t * a min/max clock rate, these rates are contained in this array.\n-\t */\n-\tstruct emc_rate_request requested_rate[EMC_RATE_TYPE_MAX];\n-\n-\t/* protect shared rate-change code path */\n-\tstruct mutex rate_lock;\n+\tstruct tegra_emc_rate_requests reqs;\n \n \tbool mrr_error;\n };\n@@ -1228,83 +1211,6 @@ static long emc_round_rate(unsigned long rate,\n \treturn timing->rate;\n }\n \n-static void tegra30_emc_rate_requests_init(struct tegra_emc *emc)\n-{\n-\tunsigned int i;\n-\n-\tfor (i = 0; i < EMC_RATE_TYPE_MAX; i++) {\n-\t\temc->requested_rate[i].min_rate = 0;\n-\t\temc->requested_rate[i].max_rate = ULONG_MAX;\n-\t}\n-}\n-\n-static int emc_request_rate(struct tegra_emc *emc,\n-\t\t\t    unsigned long new_min_rate,\n-\t\t\t    unsigned long new_max_rate,\n-\t\t\t    enum emc_rate_request_type type)\n-{\n-\tstruct emc_rate_request *req = emc->requested_rate;\n-\tunsigned long min_rate = 0, max_rate = ULONG_MAX;\n-\tunsigned int i;\n-\tint err;\n-\n-\t/* select minimum and maximum rates among the requested rates */\n-\tfor (i = 0; i < EMC_RATE_TYPE_MAX; i++, req++) {\n-\t\tif (i == type) {\n-\t\t\tmin_rate = max(new_min_rate, min_rate);\n-\t\t\tmax_rate = min(new_max_rate, max_rate);\n-\t\t} else {\n-\t\t\tmin_rate = max(req->min_rate, min_rate);\n-\t\t\tmax_rate = min(req->max_rate, max_rate);\n-\t\t}\n-\t}\n-\n-\tif (min_rate > max_rate) {\n-\t\tdev_err_ratelimited(emc->dev, \"%s: type %u: out of range: %lu %lu\\n\",\n-\t\t\t\t    __func__, type, min_rate, max_rate);\n-\t\treturn -ERANGE;\n-\t}\n-\n-\t/*\n-\t * EMC rate-changes should go via OPP API because it manages voltage\n-\t * changes.\n-\t */\n-\terr = dev_pm_opp_set_rate(emc->dev, min_rate);\n-\tif (err)\n-\t\treturn err;\n-\n-\temc->requested_rate[type].min_rate = new_min_rate;\n-\temc->requested_rate[type].max_rate = new_max_rate;\n-\n-\treturn 0;\n-}\n-\n-static int emc_set_min_rate(struct tegra_emc *emc, unsigned long rate,\n-\t\t\t    enum emc_rate_request_type type)\n-{\n-\tstruct emc_rate_request *req = &emc->requested_rate[type];\n-\tint ret;\n-\n-\tmutex_lock(&emc->rate_lock);\n-\tret = emc_request_rate(emc, rate, req->max_rate, type);\n-\tmutex_unlock(&emc->rate_lock);\n-\n-\treturn ret;\n-}\n-\n-static int emc_set_max_rate(struct tegra_emc *emc, unsigned long rate,\n-\t\t\t    enum emc_rate_request_type type)\n-{\n-\tstruct emc_rate_request *req = &emc->requested_rate[type];\n-\tint ret;\n-\n-\tmutex_lock(&emc->rate_lock);\n-\tret = emc_request_rate(emc, req->min_rate, rate, type);\n-\tmutex_unlock(&emc->rate_lock);\n-\n-\treturn ret;\n-}\n-\n /*\n  * debugfs interface\n  *\n@@ -1375,7 +1281,7 @@ static int tegra30_emc_debug_min_rate_set(void *data, u64 rate)\n \tif (!tegra30_emc_validate_rate(emc, rate))\n \t\treturn -EINVAL;\n \n-\terr = emc_set_min_rate(emc, rate, EMC_RATE_DEBUG);\n+\terr = tegra_emc_set_min_rate(&emc->reqs, rate, TEGRA_EMC_RATE_DEBUG);\n \tif (err < 0)\n \t\treturn err;\n \n@@ -1405,7 +1311,7 @@ static int tegra30_emc_debug_max_rate_set(void *data, u64 rate)\n \tif (!tegra30_emc_validate_rate(emc, rate))\n \t\treturn -EINVAL;\n \n-\terr = emc_set_max_rate(emc, rate, EMC_RATE_DEBUG);\n+\terr = tegra_emc_set_max_rate(&emc->reqs, rate, TEGRA_EMC_RATE_DEBUG);\n \tif (err < 0)\n \t\treturn err;\n \n@@ -1511,7 +1417,7 @@ static int emc_icc_set(struct icc_node *src, struct icc_node *dst)\n \tdo_div(rate, ddr * dram_data_bus_width_bytes);\n \trate = min_t(u64, rate, U32_MAX);\n \n-\terr = emc_set_min_rate(emc, rate, EMC_RATE_ICC);\n+\terr = tegra_emc_set_min_rate(&emc->reqs, rate, TEGRA_EMC_RATE_ICC);\n \tif (err)\n \t\treturn err;\n \n@@ -1622,7 +1528,6 @@ static int tegra30_emc_probe(struct platform_device *pdev)\n \tif (IS_ERR(emc->mc))\n \t\treturn PTR_ERR(emc->mc);\n \n-\tmutex_init(&emc->rate_lock);\n \temc->clk_nb.notifier_call = emc_clk_change_notify;\n \temc->dev = &pdev->dev;\n \n@@ -1664,7 +1569,7 @@ static int tegra30_emc_probe(struct platform_device *pdev)\n \t\treturn err;\n \n \tplatform_set_drvdata(pdev, emc);\n-\ttegra30_emc_rate_requests_init(emc);\n+\ttegra_emc_rate_requests_init(&emc->reqs, &pdev->dev);\n \ttegra30_emc_debugfs_init(emc);\n \ttegra30_emc_interconnect_init(emc);\n \n",
    "prefixes": [
        "v3"
    ]
}