get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2224321,
    "url": "http://patchwork.ozlabs.org/api/1.2/patches/2224321/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linux-tegra/patch/20260417-memory-refactor-v2-1-1669de38798f@nvidia.com/",
    "project": {
        "id": 21,
        "url": "http://patchwork.ozlabs.org/api/1.2/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,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260417-memory-refactor-v2-1-1669de38798f@nvidia.com>",
    "list_archive_url": null,
    "date": "2026-04-17T09:19:10",
    "name": "[v2] memory: tegra: Deduplicate rate request management code",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "fae4e125405551485ac6b02e8d2f27d88c28cefb",
    "submitter": {
        "id": 26499,
        "url": "http://patchwork.ozlabs.org/api/1.2/people/26499/?format=api",
        "name": "Mikko Perttunen",
        "email": "mperttunen@nvidia.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linux-tegra/patch/20260417-memory-refactor-v2-1-1669de38798f@nvidia.com/mbox/",
    "series": [
        {
            "id": 500289,
            "url": "http://patchwork.ozlabs.org/api/1.2/series/500289/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/linux-tegra/list/?series=500289",
            "date": "2026-04-17T09:19:10",
            "name": "[v2] memory: tegra: Deduplicate rate request management code",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/500289/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2224321/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2224321/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "\n <linux-tegra+bounces-13787-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=hQ9Q7reO;\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-13787-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=\"hQ9Q7reO\"",
            "smtp.subspace.kernel.org;\n arc=fail smtp.client-ip=52.101.52.23",
            "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)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fxqDH0jcwz1yDF\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 17 Apr 2026 19:22:55 +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 14E2A3071008\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 17 Apr 2026 09:19:37 +0000 (UTC)",
            "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id B933C3B19BB;\n\tFri, 17 Apr 2026 09:19:36 +0000 (UTC)",
            "from BL2PR02CU003.outbound.protection.outlook.com\n (mail-eastusazon11011023.outbound.protection.outlook.com [52.101.52.23])\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 2B36F3B3C11;\n\tFri, 17 Apr 2026 09:19:31 +0000 (UTC)",
            "from SJ2PR12MB9161.namprd12.prod.outlook.com (2603:10b6:a03:566::20)\n by PH7PR12MB6492.namprd12.prod.outlook.com (2603:10b6:510:1f3::10) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9818.25; Fri, 17 Apr\n 2026 09:19:25 +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.9818.023; Fri, 17 Apr 2026\n 09:19:25 +0000"
        ],
        "ARC-Seal": [
            "i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1776417576; cv=fail;\n b=IjUszCGcuGeq6KowH+lJaZTKhm/EM0n/UET1YPL4xufAZedBP/4qMa+jGWU6tdAxpwDAX3u7mvFhqytbilE1dhHYiBWwf6KJUtSIA+QTXBrD1SS7Zf9FxzmfyLoDPadqiBQ/tOxTb6RkoC+QAE12sYS025HfRbpb2UWOwclKdKE=",
            "i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;\n b=SzCILw7fPnpvC7Y4buzH03ryR7pvbs+2m4meUrkLqmJ6LABSm8zZbJf2OWBHVwqMFMLQpYGG8diEIfXSxUBpGoN08DtH5WWm80JYSfqnIeVlLx+GtFbUYJGzbXMFV++Av1XCQ59X11FI48HfJc5waOVScOuFlERV8aiWQt/+Z31YS+QaWFrlQOTYz5h/fKoACRU8uMbLcuWRD/QhUOjls84LIb6gUUCrx2JYBPsuVuGeSg67MjFQCJwxoBOAIJ1TDNVNyqz47k7Awp9RIUbMJxzasJQKsnNrPbZP2TQoTFl3cHLKVO6RMram6EJ+NqCpNR9WlkaPRfF2XlCLulHbpw=="
        ],
        "ARC-Message-Signature": [
            "i=2; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1776417576; c=relaxed/simple;\n\tbh=ntLQD8v2cz0ayrFre9q16zfHex78QpY+zIdo9Rtkv1g=;\n\th=From:Date:Subject:Content-Type:Message-Id:To:Cc:MIME-Version;\n b=XdtOHkJJDsAhXKshLGwBo9TiduB7HfWuu3yGYe81ifipi70z4BUEhFqQPrJ2imAyKyByHlxpPI5v9y75Xf2dEju/tk6QPxb7mxEi+PWLwfPu0esPa55bMYsQnACFV2Us2rYqky0r8PyI3iaY+BQ4ie7ZUg85+DUjlU7A5dZlOVg=",
            "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=IlHxl90aPfsuCvd7tA3LvzhsXqRGe6EBMeBQmtgWYpg=;\n b=kDz9ANOce4hgyTFT1ZmhpTroWsdONyWNFoioWCss83F7UloGy5N0tqC7WSqO95+ShYu0Zy0Rubc4Pu1jC+4D6Miy1gfojz2uHsWLT8OU4lSQ365mAUv399gS3rFRYa2AdidU4txXx+Fhb+Q16AVzXV42Mb3DvrXr2zDocjjBUN1uAsCtXr/LGskRAF3vQ7Gebtkfw9Wpxd6UUWQe9kKUn1296EHz0iIXsSKH7Oa96RYCp+QQLABXhM2fqL/UD4Ow+2P30k7vp+rh4HkSYrN5nftqHgqy8T19TOpYmAcC92c3GaD8kJE+RsZL5Q7m+JLaJcEwIPs7+Q8rIN0OBCP29Q=="
        ],
        "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=hQ9Q7reO; arc=fail smtp.client-ip=52.101.52.23",
            "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=IlHxl90aPfsuCvd7tA3LvzhsXqRGe6EBMeBQmtgWYpg=;\n b=hQ9Q7reOtq7eWHVd/8R6IJtRPRJkeOR0YCY7/CHkRxLWPPwGMfNYxz3ZbSdJJn35R1vUBbWk3dfBb12VJq6697shocqTZZs54CYZZdW+qZ7uxdhy99GWUnlODuK17HcJHj8pw6gnRZQUTLU/Ipi9rI/s6rWB9OSxTkb9Wxh5QmLH9bFJ4zSXHKSGaOuqVRslTEQMIGiD3pxae4Hb5GsOMyDyQXds+RrPBOIUlvpcMjMqedyj+aSQX6S9heIsrNlsdKCMjtCL0MGN7/S8++Nqi8KbkBCdjfNLfyqdA8S4FPeY2hayB5wzsNn5NNSAGpRdlo9+fHAKjHSlU/ReWtek/w==",
        "From": "Mikko Perttunen <mperttunen@nvidia.com>",
        "Date": "Fri, 17 Apr 2026 18:19:10 +0900",
        "Subject": "[PATCH v2] memory: tegra: Deduplicate rate request management code",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "7bit",
        "Message-Id": "<20260417-memory-refactor-v2-1-1669de38798f@nvidia.com>",
        "X-B4-Tracking": "v=1; b=H4sIAAAAAAAC/y2Myw5AMBBFf0VmrUlTj+BXxKKpwSwoU4SIfzfB8\n tybcy4IyIQBqugCxp0C+UnAxBG4wU49KmqFwWiTa6MTNeLo+VSMnXWrZ5WlNtdFaYvWdSDWLA8\n db7FuPmZcNgmv/3jfDw5YMxl2AAAA",
        "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.15.1",
        "X-ClientProxiedBy": "OS3P301CA0002.JPNP301.PROD.OUTLOOK.COM\n (2603:1096:604:21d::7) 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_|PH7PR12MB6492:EE_",
        "X-MS-Office365-Filtering-Correlation-Id": "7732b787-e98b-4b10-afca-08de9c626b3a",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "\n\tBCL:0;ARA:13230040|10070799003|366016|376014|1800799024|18002099003|56012099003;",
        "X-Microsoft-Antispam-Message-Info": "\n\t88pXX4/d9//AV06xfojcWOKiisS7/eBw8SFm5kPWbItv/6GMJcg8b6AxjlBz72k2md1v4MJBpbD39akoVUXxQM7cW2cGtYaA2lp6cTeoLd/2vD8PqIw3oV5D8QaB8P4SwMre3zR8al4d6rWPu5CTFguZdvUmQlH//ylgSZvTw6omundQEzHz1pJSzOdaktHIBieXWFGgjDtTmhUSvTYuuKuJhhLCk0o0kHEV89r3VXkAh9c5/8+9eofd3NS/k2jEdFUO+yShqiMBSHos/MgA+UB8afV3ycqXdj6IMl+wSGueJkyeSLWYiNmC6wVZpSBuQj4eoF8mHEgg44ogq82IHufVFXBPLoQFAP1CNzEw3pUmSQZDODclvT7K0l1EQP/aiCeXEznnfwMqic+CzqLSFNdW+xNo39qCMGLImYs5ByOhEs254j+rDeAdmCNmCz9Zp47vZY8yqBmIijj5ngdalA0tTDlafpIsVesZXRtHmNM5StaClMSejW8vp6HNsQr4yptg8yGHee3mBB4YQrT/gJnrxTvPqL/o7bNZr6xxHikhFI16d9qpaa24jF6zM4p9D9QB663rb+tuboPxZQu4YaOFm+R/PeH97lEYru/Ve9f2CrUuPwB061JVDNqxK8HdPOGZow8vg0hIcesWdmo2MoAd9AFhgNT6VTxtn0bakHwOg1MMaJbL5tgAdaOfNiF1dqEtfBoa7lKKFxT2tNoBoQiojIeX5C9w3ahWn5jHle4=",
        "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)(10070799003)(366016)(376014)(1800799024)(18002099003)(56012099003);DIR:OUT;SFP:1101;",
        "X-MS-Exchange-AntiSpam-MessageData-ChunkCount": "2",
        "X-MS-Exchange-AntiSpam-MessageData-0": "=?utf-8?q?ub5+dpoEpEmV8XZaJIbVOFs8szh7?=\n\t=?utf-8?q?zN6BqoEvs18cG/C3Zoi8Xp/4k1yJL+Xq9G2IRZyAMnmVnNtssBrvvn3ZaAK8kK5dU?=\n\t=?utf-8?q?7EXbDfeYnheLJIU2UgmE0O7uFqVnfcOVKeM5yV70SUZ26hGbhOKDm/HbjBkEhMduK?=\n\t=?utf-8?q?xq9rVTpvdBPAcrFbvOJ0es4ErHjBsx/Hnwpbfv1bCf/eJv5OC0uoQO0jxbw67N5sF?=\n\t=?utf-8?q?CHW42EzrP6D05CcoDvSYYF/nwrFK6uBD7tf9iJjgZxUV9VXQN3jJP1F9glp6VtZQg?=\n\t=?utf-8?q?qdugdD7nGEl1e9dXZjmj+WnKigzJeLPVTJmoVigC2dxRheJMy8eMofhzr+Qf72uqC?=\n\t=?utf-8?q?8PFD5MqvE/x5iGBv/wHO3ovsKYqAYoZbUwZFRj2E2FU/j31KyoIELbJGOteI5Q5CG?=\n\t=?utf-8?q?+XH/6RPkNPND2bJhU16Ev3TiFDXWS5QzuAdGKTGq8coTyb9RjV+I3BcT+h0ZH+G7D?=\n\t=?utf-8?q?LmEB57E31wnvWIejrhNSs1aPY7pBRYDSnKrwndRMeTf2QGGiftKi81AG3aRsdqYfZ?=\n\t=?utf-8?q?XTASnmoOX7/sb1pmEvSGGxr1fRZJc//en4B0ueJ+HX/CUWofQyjS/Ep218Y+xb++P?=\n\t=?utf-8?q?1figEwDjgX2PAma4srPkltTcUvIoaqE2SP+bZc5hQcrHbVhqMjWgMOWPJOoKea5F+?=\n\t=?utf-8?q?S7EQ6zweGwpGw0MF5hjVfwkXAIE6gWJYVw8TB6vA41aurDct2cqBU9OvjUVD/uQI2?=\n\t=?utf-8?q?4apyAUa9fstWT9YcNUk0nCic3uwjNnC4wSZQWIGjsZnpKOq3GujufkomAVfrDxr0s?=\n\t=?utf-8?q?SlCNoVfAEYfHDphwINv2ILh6DRK03dcId3rujTb9KfOc3oN99Pmwg1uRSbl1kzxI9?=\n\t=?utf-8?q?tF7pfBE/xhAVUDWHS9GkKarM7mYr1vU3H1F3SJ8smo/wOcZKl3ifJjxh94qNE95+f?=\n\t=?utf-8?q?f6us5yKXdFVOm5YthpMrYbkJlSbJCxIU09nUZT/tDtBDUEEvf4fkWZfqVZi5aXOd/?=\n\t=?utf-8?q?svYs+QUo6Czeuy7wcHnwPTU0c3xsMFu3UnEgXVMnY4+JN4YsgaRWg0FJB8urZm2la?=\n\t=?utf-8?q?MzuMXtIxm7wMikiATN8/t6vbdiZeDEDKob3U5i1n7BGVb4cWP+BimeDIhnapD4WqR?=\n\t=?utf-8?q?O3+6Xpk62Fl6yp5p+yH2p92uHR3lTXJGAYAoFVUFG2Ba3Hz0nOAWaPZUT4Cm9Ulil?=\n\t=?utf-8?q?bJViOl5t/LYiRsjA8Ey1e5FWxdztQ+qLrIlGM23Rv+Fh0PueZJrC1K7oQW9fzTv3y?=\n\t=?utf-8?q?pdy/N89T05EvtUNGdjEnVmf48xOx8sYSK/XmMvTHOQDsBbKKZx5tLWSizi2lGq1pn?=\n\t=?utf-8?q?y8hNT9iSXAUHR4IJnRlCMzqi/SgjZK3UFLcywpnYboSaneNP+EZ3ORPQySQpvJOTz?=\n\t=?utf-8?q?xUjLlo4F5ByVat584J/qlKHNZuuV1vbT9Ewt+OtFKptRo5prtqZZgxKeMD4kDivCE?=\n\t=?utf-8?q?+CTMSAj9Wf/9oOpKVjyI5zXEXcfDot4Fn8X+ikZL1HPmwNlFsu2cCk/VulYdImw/a?=\n\t=?utf-8?q?UwysfAhj0yBYD4/yOgzo8Fv+rs4145BNdWbz1aZ7ValuwVqLibY8GDFmPoJ5RxLES?=\n\t=?utf-8?q?zCbXCQgfWQ8VWF5AongA+9dm2W4JmnpPscb+PUBGdyJyOSbXjfL3MxppzEE112dM/?=\n\t=?utf-8?q?Fqy+hIdmFfYLMTVpLlebUBCDdMSVwp2iH6qTnqxQzn228LFHT3hXJq7I1DX3Qc6+g?=\n\t=?utf-8?q?3IBK6Hcof6yuJhhn7TTH7BK2d7wPJJfWGO/HyiPpDbVzL1F9ywd2iZDPNpyKYx+r7?=\n\t=?utf-8?q?3egOxiFSGHuiu9wNq?=",
        "X-MS-Exchange-AntiSpam-MessageData-1": "jH3LZ4d1fC9f2Q==",
        "X-OriginatorOrg": "Nvidia.com",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 7732b787-e98b-4b10-afca-08de9c626b3a",
        "X-MS-Exchange-CrossTenant-AuthSource": "SJ2PR12MB9161.namprd12.prod.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Internal",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "17 Apr 2026 09:19:25.6300\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 /ZPdtBefG4RunyHDTSs2A1cjzUvH671e6cDyqWCbc2ZfID7EA5JjHM6dYvKHIecGpVes9ZGQX/rUReWe9+9D2w==",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "PH7PR12MB6492"
    },
    "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---\nv2:\n- Add kerneldoc comments.\n- Add note about source of the code to commit message.\n- Drop the Tegra114 EMC series as dependency. Rebase on v7.0.\n---\n drivers/memory/tegra/Kconfig            |   6 ++\n drivers/memory/tegra/Makefile           |   1 +\n drivers/memory/tegra/tegra-emc-common.c | 139 ++++++++++++++++++++++++++++++++\n drivers/memory/tegra/tegra-emc-common.h |  45 +++++++++++\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, 210 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..2bd766842fa5\n--- /dev/null\n+++ b/drivers/memory/tegra/tegra-emc-common.c\n@@ -0,0 +1,139 @@\n+// SPDX-License-Identifier: GPL-2.0\n+\n+#include <linux/device.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+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+\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..80e26fb13830\n--- /dev/null\n+++ b/drivers/memory/tegra/tegra-emc-common.h\n@@ -0,0 +1,45 @@\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+\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": [
        "v2"
    ]
}