get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 812813,
    "url": "http://patchwork.ozlabs.org/api/patches/812813/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/devicetree-bindings/patch/1505217667-31184-1-git-send-email-vivek.gautam@codeaurora.org/",
    "project": {
        "id": 37,
        "url": "http://patchwork.ozlabs.org/api/projects/37/?format=api",
        "name": "Devicetree Bindings",
        "link_name": "devicetree-bindings",
        "list_id": "devicetree.vger.kernel.org",
        "list_email": "devicetree@vger.kernel.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<1505217667-31184-1-git-send-email-vivek.gautam@codeaurora.org>",
    "list_archive_url": null,
    "date": "2017-09-12T12:01:07",
    "name": "[RFC,1/1] iommu/arm-smmu: Add support for multiple TBU child devices",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "facfcc437d73837ba3b25c02416bec7389b8b354",
    "submitter": {
        "id": 69805,
        "url": "http://patchwork.ozlabs.org/api/people/69805/?format=api",
        "name": "Vivek Gautam",
        "email": "vivek.gautam@codeaurora.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/devicetree-bindings/patch/1505217667-31184-1-git-send-email-vivek.gautam@codeaurora.org/mbox/",
    "series": [
        {
            "id": 2683,
            "url": "http://patchwork.ozlabs.org/api/series/2683/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/devicetree-bindings/list/?series=2683",
            "date": "2017-09-12T12:01:07",
            "name": "[RFC,1/1] iommu/arm-smmu: Add support for multiple TBU child devices",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/2683/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/812813/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/812813/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<devicetree-owner@vger.kernel.org>",
        "X-Original-To": "incoming-dt@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming-dt@bilbo.ozlabs.org",
        "Authentication-Results": [
            "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=devicetree-owner@vger.kernel.org; receiver=<UNKNOWN>)",
            "ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=codeaurora.org header.i=@codeaurora.org\n\theader.b=\"EpvSuOdS\"; \n\tdkim=fail reason=\"signature verification failed\" (1024-bit key)\n\theader.d=codeaurora.org header.i=@codeaurora.org header.b=\"N9MLK9nU\"; \n\tdkim-atps=neutral",
            "pdx-caf-mail.web.codeaurora.org;\n\tdmarc=none (p=none dis=none) header.from=codeaurora.org",
            "pdx-caf-mail.web.codeaurora.org;\n\tspf=none smtp.mailfrom=vivek.gautam@codeaurora.org"
        ],
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xs3LP6yjCz9t2f\n\tfor <incoming-dt@patchwork.ozlabs.org>;\n\tTue, 12 Sep 2017 22:01:39 +1000 (AEST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751460AbdILMBY (ORCPT\n\t<rfc822;incoming-dt@patchwork.ozlabs.org>);\n\tTue, 12 Sep 2017 08:01:24 -0400",
            "from smtp.codeaurora.org ([198.145.29.96]:60000 \"EHLO\n\tsmtp.codeaurora.org\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1751379AbdILMBX (ORCPT\n\t<rfc822; devicetree@vger.kernel.org>); Tue, 12 Sep 2017 08:01:23 -0400",
            "by smtp.codeaurora.org (Postfix, from userid 1000)\n\tid 878EB60879; Tue, 12 Sep 2017 12:01:22 +0000 (UTC)",
            "from blr-ubuntu-41.ap.qualcomm.com\n\t(blr-bdr-fw-01_globalnat_allzones-outside.qualcomm.com\n\t[103.229.18.19])\n\t(using TLSv1.1 with cipher ECDHE-RSA-AES128-SHA (128/128 bits))\n\t(No client certificate requested)\n\t(Authenticated sender: vivek.gautam@smtp.codeaurora.org)\n\tby smtp.codeaurora.org (Postfix) with ESMTPSA id 79005607DC;\n\tTue, 12 Sep 2017 12:01:17 +0000 (UTC)"
        ],
        "DKIM-Signature": [
            "v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org;\n\ts=default; t=1505217682;\n\tbh=bRn3nulZdTG8faFdW74ncecQD4PmPBBs+STOltctnl8=;\n\th=From:To:Cc:Subject:Date:From;\n\tb=EpvSuOdSgaO/QPH4c6MqH7QWc2QfOZZJnvsT6s5znlHE8BN/abqPi7fxm6S2t0bIr\n\tud2XtejyK5W9I0dUgB538c3esxkXhRKvvV+lmDWGWFpRWaXCoiPTvG2cQUAs2CwFAg\n\tjpcJOiXylVfKOZvXAqSkrqSIKSvyIdGP0Byy+tGk=",
            "v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org;\n\ts=default; t=1505217680;\n\tbh=bRn3nulZdTG8faFdW74ncecQD4PmPBBs+STOltctnl8=;\n\th=From:To:Cc:Subject:Date:From;\n\tb=N9MLK9nUEDVAGDj5jR+drLKRvM2jJMn5rPvE9ivoknnI8sHRjCYG39m1DDk/ipxI7\n\tdxKkBdJYVfz2YNa76E4laVfp7Nzmh6VbPZmDvg4CRx/pNULW7lY7i2571G74WUvKqL\n\te6dLoeOfty25TjjSf+uU6Y42MhJwC9glKNZJc55o="
        ],
        "X-Spam-Checker-Version": "SpamAssassin 3.4.0 (2014-02-07) on\n\tpdx-caf-mail.web.codeaurora.org",
        "X-Spam-Level": "",
        "X-Spam-Status": "No, score=-2.8 required=2.0 tests=ALL_TRUSTED,BAYES_00,\n\tDKIM_SIGNED,\n\tT_DKIM_INVALID autolearn=no autolearn_force=no version=3.4.0",
        "DMARC-Filter": "OpenDMARC Filter v1.3.2 smtp.codeaurora.org 79005607DC",
        "From": "Vivek Gautam <vivek.gautam@codeaurora.org>",
        "To": "robin.murphy@arm.com, will.deacon@arm.com, robh+dt@kernel.org,\n\tiommu@lists.linux-foundation.org, devicetree@vger.kernel.org",
        "Cc": "joro@8bytes.org, linux-kernel@vger.kernel.org,\n\tlinux-arm-kernel@lists.infradead.org, mark.rutland@arm.com,\n\tlinux-arm-msm@vger.kernel.org, Vivek Gautam <vivek.gautam@codeaurora.org>",
        "Subject": "[RFC PATCH 1/1] iommu/arm-smmu: Add support for multiple TBU child\n\tdevices",
        "Date": "Tue, 12 Sep 2017 17:31:07 +0530",
        "Message-Id": "<1505217667-31184-1-git-send-email-vivek.gautam@codeaurora.org>",
        "X-Mailer": "git-send-email 1.9.1",
        "Sender": "devicetree-owner@vger.kernel.org",
        "Precedence": "bulk",
        "List-ID": "<devicetree.vger.kernel.org>",
        "X-Mailing-List": "devicetree@vger.kernel.org"
    },
    "content": "ARM MMU-500 implements a TBU (uTLB) for each connected master\nbesides a single TCU which controls and manages the address\ntranslations. Each of these TBUs can either be in the same\npower domain as the master, or they can have a independent\npower switch.\nThis design addresses the challenges to control TBU power.\nAdding child devices for each TBUs present in the configuration\nlets us control the power and clocks to TLBs having individual\npower domains. The device link between master devices (such as,\ndisplay, and GPU) and TBU devices ensures that the master takes\ncare of powering the smmu as long as it's available.\nWhen the master is not available, the TBUs are identified with\nsid and powered on.\n\nSigned-off-by: Vivek Gautam <vivek.gautam@codeaurora.org>\n---\n\n - The idea behind this patch is to handle the distributed smmu\n   architectures, similar to MMU-500.\n - Untested yet.\n - There are still few instances where the correct tbu device has\n   to be referenced and thus powered on to handle TLB maintenance\n   operations.\n\n .../devicetree/bindings/iommu/arm,smmu.txt         |  27 +++\n drivers/iommu/arm-smmu.c                           | 191 +++++++++++++++++++--\n 2 files changed, 205 insertions(+), 13 deletions(-)",
    "diff": "diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt\nindex d97a6bc8e608..7cf67e75022e 100644\n--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt\n+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt\n@@ -98,6 +98,18 @@ conditions.\n                   accessed before master gets enabled and linked to its\n                   SMMU.\n \n+- child nodes:    ARM MMU-500 implements a TBU (page table cache or TLB) for\n+                  each connected master besides a single TCU that controls\n+                  and manages the address translations.\n+                  Each of the child nodes represents a TBU that is attached to\n+                  the master. This child node will have following property:\n+\n+  - compatibe:       must be \"arm,mmu-500-tbu\" for TBU child nodes of arm,mmu-500\n+                     smmu.\n+  - stream-id-range: array representing the starting stream id and the number\n+                     of supported stream-ids. This gives information about\n+                     the range of stream-ids that are supported by this TBU.\n+\n ** Deprecated properties:\n \n - mmu-masters (deprecated in favour of the generic \"iommus\" binding) :\n@@ -187,3 +199,18 @@ conditions.\n \t\t\t <&mmcc SMMU_MDP_AHB_CLK>;\n \t\tclock-names = \"bus\", \"iface\";\n \t};\n+\n+\tsmmu4: iommu {\n+\t\tcompatible = \"arm,mmu-500\";\n+\t\treg = <0xd00000 0x10000>;\n+                ...\n+                ...\n+                #address-cells = <1>;\n+                #size-cells = <0>;\n+\n+                tbu: tbu@0 {\n+                         compatible = \"arm,mmu-500-tbu\";\n+                         reg = <0>;\n+                         stream-id-range = <0x0 0x400>;\n+                };\n+        };\ndiff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c\nindex 14137e389071..ba84693e2de3 100644\n--- a/drivers/iommu/arm-smmu.c\n+++ b/drivers/iommu/arm-smmu.c\n@@ -224,6 +224,8 @@ struct arm_smmu_device {\n \n \t/* IOMMU core code handle */\n \tstruct iommu_device\t\tiommu;\n+\n+\tstruct list_head\t\ttbu_list;\n };\n \n enum arm_smmu_context_fmt {\n@@ -333,6 +335,33 @@ static int __find_legacy_master_phandle(struct device *dev, void *data)\n static struct platform_driver arm_smmu_driver;\n static struct iommu_ops arm_smmu_ops;\n \n+struct arm_smmu500_tbu {\n+\tstruct device *dev;\n+\tu32 sid_range[2];\n+\tstruct list_head list;\n+\tstruct arm_smmu_device *smmu;\n+};\n+\n+static struct device *find_tbu(struct device *parent, u16 sid)\n+{\n+\tstruct arm_smmu_device *smmu = dev_get_drvdata(parent);\n+\tstruct arm_smmu500_tbu *tbu;\n+\tu32 start, end;\n+\tstruct device *dev = NULL;\n+\n+\tlist_for_each_entry(tbu, &smmu->tbu_list, list) {\n+\t\tstart = tbu->sid_range[0];\n+\t\tend = start + tbu->sid_range[1];\n+\n+\t\tif (start <= sid && sid < end) {\n+\t\t\tdev = tbu->dev;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\treturn dev;\n+}\n+\n static int arm_smmu_register_legacy_master(struct device *dev,\n \t\t\t\t\t   struct arm_smmu_device **smmu)\n {\n@@ -927,6 +956,7 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain)\n \tif (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY)\n \t\treturn;\n \n+\t/* TODO Get the TBU dev power it on; or turn on all the TBUs? */\n \tret = pm_runtime_get_sync(smmu->dev);\n \tif (ret)\n \t\treturn;\n@@ -1379,6 +1409,8 @@ static int arm_smmu_add_device(struct device *dev)\n \tstruct iommu_fwspec *fwspec = dev->iommu_fwspec;\n \tstruct device_link *link;\n \tint i, ret;\n+\tu16 sid;\n+\tstruct device *tbu_dev;\n \n \tif (using_legacy_binding) {\n \t\tret = arm_smmu_register_legacy_master(dev, &smmu);\n@@ -1425,29 +1457,42 @@ static int arm_smmu_add_device(struct device *dev)\n \twhile (i--)\n \t\tcfg->smendx[i] = INVALID_SMENDX;\n \n-\tret = pm_runtime_get_sync(smmu->dev);\n+\t/*\n+\t * Find out the correct TBU for this master based on the\n+\t * steamID, and then create the device link between them.\n+\t */\n+\t/* TODO: Iterate over all the SIDs, and turn them on? */\n+\tsid = fwspec->ids[0];\n+\ttbu_dev = find_tbu(smmu->dev, sid);\n+\tif (!tbu_dev)\n+\t\ttbu_dev = smmu->dev;\n+\n+\tret = pm_runtime_get_sync(tbu_dev);\n \tif (ret)\n \t\tgoto out_cfg_free;\n \n \tret = arm_smmu_master_alloc_smes(dev);\n \tif (ret) {\n-\t\tpm_runtime_put_sync(smmu->dev);\n+\t\tpm_runtime_put_sync(tbu_dev);\n \t\tgoto out_cfg_free;\n \t}\n \n \tiommu_device_link(&smmu->iommu, dev);\n \n-\tpm_runtime_put_sync(smmu->dev);\n+\tpm_runtime_put_sync(tbu_dev);\n \n \t/*\n \t * Establish the link between smmu and master, so that the\n \t * smmu gets runtime enabled/disabled as per the master's\n \t * needs.\n+\t * TBU devices are children to the smmu device, so creating link\n+\t * between TBU devices and master takes care of turning on the smmu\n+\t * as well.\n \t */\n-\tlink = device_link_add(dev, smmu->dev, DL_FLAG_PM_RUNTIME);\n+\tlink = device_link_add(dev, tbu_dev, DL_FLAG_PM_RUNTIME);\n \tif (!link)\n \t\tdev_warn(smmu->dev, \"Unable to create device link between %s and %s\\n\",\n-\t\t\t dev_name(smmu->dev), dev_name(dev));\n+\t\t\t dev_name(tbu_dev), dev_name(dev));\n \n \treturn 0;\n \n@@ -1464,6 +1509,8 @@ static void arm_smmu_remove_device(struct device *dev)\n \tstruct arm_smmu_master_cfg *cfg;\n \tstruct arm_smmu_device *smmu;\n \tint ret;\n+\tu16 sid;\n+\tstruct device *tbu_dev;\n \n \tif (!fwspec || fwspec->ops != &arm_smmu_ops)\n \t\treturn;\n@@ -1476,15 +1523,20 @@ static void arm_smmu_remove_device(struct device *dev)\n \t * smmu is already purged at this point.\n \t * So enable the power to smmu explicitly.\n \t */\n+\tsid = fwspec->ids[0];\n \n-\tret = pm_runtime_get_sync(smmu->dev);\n+\ttbu_dev = find_tbu(smmu->dev, sid);\n+\tif (!tbu_dev)\n+\t\ttbu_dev = smmu->dev;\n+\n+\tret = pm_runtime_get_sync(tbu_dev);\n \tif (ret)\n \t\treturn;\n \n \tiommu_device_unlink(&smmu->iommu, dev);\n \tarm_smmu_master_free_smes(fwspec);\n \n-\tpm_runtime_put_sync(smmu->dev);\n+\tpm_runtime_put_sync(tbu_dev);\n \n \tiommu_group_remove_device(dev);\n \tkfree(fwspec->iommu_priv);\n@@ -2012,6 +2064,32 @@ struct arm_smmu_match_data {\n };\n MODULE_DEVICE_TABLE(of, arm_smmu_of_match);\n \n+static const struct of_device_id arm_smmu_tbu_of_match[] = {\n+\t{ .compatible = \"arm,mmu-500-tbu\", },\n+\t{},\n+};\n+MODULE_DEVICE_TABLE(of, arm_smmu_tbu_of_match);\n+\n+static int arm_smmu_tbu_register(struct device *dev, void *cookie)\n+{\n+\tstruct arm_smmu_device *smmu = cookie;\n+\tstruct arm_smmu500_tbu *tbu;\n+\n+\tif (!dev->driver) {\n+\t\tdev_err(dev, \"TBU failed probe, SMMUV500 cannot continue!\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\ttbu = dev_get_drvdata(dev);\n+\n+\tINIT_LIST_HEAD(&tbu->list);\n+\ttbu->smmu = smmu;\n+\tlist_add_tail(&tbu->list, &smmu->tbu_list);\n+\n+\treturn 0;\n+}\n+\n+\n #ifdef CONFIG_ACPI\n static int acpi_smmu_get_data(u32 model, struct arm_smmu_device *smmu)\n {\n@@ -2140,6 +2218,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)\n \tresource_size_t ioaddr;\n \tstruct arm_smmu_device *smmu;\n \tstruct device *dev = &pdev->dev;\n+\tstruct arm_smmu500_tbu *tbu;\n \tint num_irqs, i, err;\n \n \tsmmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);\n@@ -2157,6 +2236,8 @@ static int arm_smmu_device_probe(struct platform_device *pdev)\n \tif (err)\n \t\treturn err;\n \n+\tINIT_LIST_HEAD(&smmu->tbu_list);\n+\n \tres = platform_get_resource(pdev, IORESOURCE_MEM, 0);\n \tioaddr = res->start;\n \tsmmu->base = devm_ioremap_resource(dev, res);\n@@ -2194,16 +2275,32 @@ static int arm_smmu_device_probe(struct platform_device *pdev)\n \t\tsmmu->irqs[i] = irq;\n \t}\n \n+\t/* MMU 500 has one TCU and multiple TBU config */\n+\tif (of_device_is_compatible(dev->of_node, \"arm,mmu-500\")) {\n+\t\terr = of_platform_populate(dev->of_node, NULL, NULL, dev);\n+\t\tif (err) {\n+\t\t\tdev_err(dev, \"failed to register TBU children\\n\");\n+\t\t\treturn err;\n+\t\t}\n+\n+\t\terr = device_for_each_child(dev, smmu, arm_smmu_tbu_register);\n+\t\tif (err)\n+\t\t\treturn -EPROBE_DEFER;\n+\t}\n+\n \terr = arm_smmu_init_clocks(smmu);\n \tif (err)\n \t\treturn err;\n \n \tplatform_set_drvdata(pdev, smmu);\n+\n \tpm_runtime_enable(dev);\n \n-\terr = pm_runtime_get_sync(dev);\n-\tif (err)\n-\t\treturn err;\n+\t/* enable all TBUs */\n+\tlist_for_each_entry(tbu, &smmu->tbu_list, list)\n+\t\terr = pm_runtime_get_sync(tbu->dev);\n+\t\tif (err)\n+\t\t\treturn err;\n \n \terr = arm_smmu_device_cfg_probe(smmu);\n \tif (err)\n@@ -2248,7 +2345,9 @@ static int arm_smmu_device_probe(struct platform_device *pdev)\n \n \tarm_smmu_device_reset(smmu);\n \tarm_smmu_test_smr_masks(smmu);\n-\tpm_runtime_put_sync(dev);\n+\n+\tlist_for_each_entry(tbu, &smmu->tbu_list, list)\n+\t\tpm_runtime_put_sync(tbu->dev);\n \n \t/*\n \t * For ACPI and generic DT bindings, an SMMU will be probed before\n@@ -2278,6 +2377,7 @@ static int arm_smmu_legacy_bus_init(void)\n static int arm_smmu_device_remove(struct platform_device *pdev)\n {\n \tstruct arm_smmu_device *smmu = platform_get_drvdata(pdev);\n+\tstruct arm_smmu500_tbu *tbu;\n \n \tif (!smmu)\n \t\treturn -ENODEV;\n@@ -2287,7 +2387,9 @@ static int arm_smmu_device_remove(struct platform_device *pdev)\n \n \t/* Turn the thing off */\n \twritel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);\n-\tpm_runtime_force_suspend(smmu->dev);\n+\n+\tlist_for_each_entry(tbu, &smmu->tbu_list, list)\n+\t\tpm_runtime_force_suspend(tbu->dev);\n \n \treturn 0;\n }\n@@ -2336,7 +2438,70 @@ static int __maybe_unused arm_smmu_suspend(struct device *dev)\n \t.remove\t= arm_smmu_device_remove,\n \t.shutdown = arm_smmu_device_shutdown,\n };\n-module_platform_driver(arm_smmu_driver);\n+\n+static int arm_smmu_tbu_probe(struct platform_device *pdev)\n+{\n+\tstruct device *dev = &pdev->dev;\n+\tstruct arm_smmu500_tbu *tbu;\n+\tint err;\n+\n+\ttbu = devm_kzalloc(dev, sizeof(*tbu), GFP_KERNEL);\n+\tif (!tbu)\n+\t\treturn -ENOMEM;\n+\n+\ttbu->dev = &pdev->dev;\n+\n+\terr = of_property_read_u32_array(dev->of_node, \"stream-id-range\",\n+\t\t\t\t\t tbu->sid_range, 2);\n+\tif (err)\n+\t\tdev_err(dev, \"failed to read stream id range\\n\");\n+\n+\tpm_runtime_enable(dev);\n+\n+\tdev_set_drvdata(dev, tbu);\n+\n+\treturn 0;\n+}\n+\n+static int arm_smmu_tbu_remove(struct platform_device *pdev)\n+{\n+\tpm_runtime_disable(&pdev->dev);\n+\n+\treturn 0;\n+}\n+\n+static struct platform_driver arm_smmu_tbu_driver = {\n+\t.driver\t= {\n+\t\t.name\t\t= \"arm-mmu-500-tbu\",\n+\t\t.of_match_table\t= of_match_ptr(arm_smmu_tbu_of_match),\n+\t},\n+\t.probe\t= arm_smmu_tbu_probe,\n+\t.remove\t= arm_smmu_tbu_remove,\n+};\n+\n+static int __init arm_smmu_init(void)\n+{\n+\tint ret;\n+\n+\tret = platform_driver_register(&arm_smmu_tbu_driver);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = platform_driver_register(&arm_smmu_driver);\n+\tif (ret)\n+\t\tplatform_driver_unregister(&arm_smmu_tbu_driver);\n+\n+\treturn ret;\n+}\n+\n+static void __init arm_smmu_exit(void)\n+{\n+\tplatform_driver_unregister(&arm_smmu_driver);\n+\tplatform_driver_unregister(&arm_smmu_tbu_driver);\n+}\n+\n+module_init(arm_smmu_init);\n+module_exit(arm_smmu_exit);\n \n IOMMU_OF_DECLARE(arm_smmuv1, \"arm,smmu-v1\", NULL);\n IOMMU_OF_DECLARE(arm_smmuv2, \"arm,smmu-v2\", NULL);\n",
    "prefixes": [
        "RFC",
        "1/1"
    ]
}