get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 816583,
    "url": "http://patchwork.ozlabs.org/api/patches/816583/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linux-imx/patch/20170920224621.16236-8-tony@atomide.com/",
    "project": {
        "id": 19,
        "url": "http://patchwork.ozlabs.org/api/projects/19/?format=api",
        "name": "Linux IMX development",
        "link_name": "linux-imx",
        "list_id": "linux-imx-kernel.lists.patchwork.ozlabs.org",
        "list_email": "linux-imx-kernel@lists.patchwork.ozlabs.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20170920224621.16236-8-tony@atomide.com>",
    "list_archive_url": null,
    "date": "2017-09-20T22:46:18",
    "name": "[07/10] bus: ti-sysc: Add minimal TI sysc interconnect target driver",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "69c06370b3750041f162f548aca3c705fc8ed41d",
    "submitter": {
        "id": 365,
        "url": "http://patchwork.ozlabs.org/api/people/365/?format=api",
        "name": "Tony Lindgren",
        "email": "tony@atomide.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linux-imx/patch/20170920224621.16236-8-tony@atomide.com/mbox/",
    "series": [
        {
            "id": 4251,
            "url": "http://patchwork.ozlabs.org/api/series/4251/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/linux-imx/list/?series=4251",
            "date": "2017-09-20T22:46:12",
            "name": "Fix remaining issues to drop more omap platform data",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/4251/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/816583/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/816583/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org>",
        "X-Original-To": "incoming-imx@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming-imx@bilbo.ozlabs.org",
        "Authentication-Results": [
            "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=lists.infradead.org\n\t(client-ip=65.50.211.133; helo=bombadil.infradead.org;\n\tenvelope-from=linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org;\n\treceiver=<UNKNOWN>)",
            "ozlabs.org; dkim=pass (2048-bit key;\n\tunprotected) header.d=lists.infradead.org\n\theader.i=@lists.infradead.org\n\theader.b=\"p/rc2vnJ\"; dkim-atps=neutral"
        ],
        "Received": [
            "from bombadil.infradead.org (bombadil.infradead.org\n\t[65.50.211.133])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xyFRj35G6z9sBZ\n\tfor <incoming-imx@patchwork.ozlabs.org>;\n\tThu, 21 Sep 2017 08:54:25 +1000 (AEST)",
            "from localhost ([127.0.0.1] helo=bombadil.infradead.org)\n\tby bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux))\n\tid 1dunsp-00039M-Dz; Wed, 20 Sep 2017 22:54:19 +0000",
            "from muru.com ([72.249.23.125])\n\tby bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux))\n\tid 1dunmH-00054n-8D for linux-arm-kernel@lists.infradead.org;\n\tWed, 20 Sep 2017 22:47:57 +0000",
            "from sampyla.muru.com (localhost [127.0.0.1])\n\tby muru.com (Postfix) with ESMTP id 66296822F;\n\tWed, 20 Sep 2017 22:47:49 +0000 (UTC)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n\td=lists.infradead.org; s=bombadil.20170209; h=Sender:\n\tContent-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post:\n\tList-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:\n\tMessage-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description:\n\tResent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:\n\tList-Owner; bh=8MKcsvNkdVD/TBZTE8cJVlmPniaIQ8qWlLU5WLaDJac=;\n\tb=p/rc2vnJZc/q3D\n\trOwSG4XvXSAIGDmxPSwh/T70MtTp2t+k8NxFKii873BHtax17HKudsEmnB8dRPtg7kelje/xwlLVx\n\tJ71yXIuNSv0BBKWaaFs49y5wFCJ3SuQEVkMRPgCQa1GZ0EW4qrP2yowL3/DuWzcTzm9/vfYVdc55l\n\tQ/FWSQBQFW7I2jOwi5k5E/Y2bWQCwt1RKu6dIPEuusNoU5pOunlK+tVkv4o/xqsxPlreDpzyP4ikk\n\tMaYgQaSjvrBnefUZjKaeYSm+fcr5vRd4uvMSklOUfKoAYVmWiPewlqIyj0UCuFxuBDQUJDJJKMQ3+\n\t9XgXiFcFdZ6AYj2CbpIA==;",
        "From": "Tony Lindgren <tony@atomide.com>",
        "To": "linux-omap@vger.kernel.org",
        "Subject": "[PATCH 07/10] bus: ti-sysc: Add minimal TI sysc interconnect target\n\tdriver",
        "Date": "Wed, 20 Sep 2017 15:46:18 -0700",
        "Message-Id": "<20170920224621.16236-8-tony@atomide.com>",
        "X-Mailer": "git-send-email 2.14.1",
        "In-Reply-To": "<20170920224621.16236-1-tony@atomide.com>",
        "References": "<20170920224621.16236-1-tony@atomide.com>",
        "MIME-Version": "1.0",
        "X-CRM114-Version": "20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 ",
        "X-CRM114-CacheID": "sfid-20170920_154737_345311_55F66E88 ",
        "X-CRM114-Status": "GOOD (  26.65  )",
        "X-Spam-Score": "-1.9 (-)",
        "X-Spam-Report": "SpamAssassin version 3.4.1 on bombadil.infradead.org summary:\n\tContent analysis details:   (-1.9 points)\n\tpts rule name              description\n\t---- ----------------------\n\t--------------------------------------------------\n\t-1.9 BAYES_00               BODY: Bayes spam probability is 0 to 1%\n\t[score: 0.0000]",
        "X-BeenThere": "linux-arm-kernel@lists.infradead.org",
        "X-Mailman-Version": "2.1.21",
        "Precedence": "list",
        "List-Unsubscribe": "<http://lists.infradead.org/mailman/options/linux-arm-kernel>,\n\t<mailto:linux-arm-kernel-request@lists.infradead.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.infradead.org/pipermail/linux-arm-kernel/>",
        "List-Post": "<mailto:linux-arm-kernel@lists.infradead.org>",
        "List-Help": "<mailto:linux-arm-kernel-request@lists.infradead.org?subject=help>",
        "List-Subscribe": "<http://lists.infradead.org/mailman/listinfo/linux-arm-kernel>,\n\t<mailto:linux-arm-kernel-request@lists.infradead.org?subject=subscribe>",
        "Cc": "Nishanth Menon <nm@ti.com>, devicetree@vger.kernel.org, Paul Walmsley\n\t<paul@pwsan.com>, Matthijs van Duin <matthijsvanduin@gmail.com>, \n\tGreg Kroah-Hartman\n\t<gregkh@linuxfoundation.org>, Tero Kristo <t-kristo@ti.com>, \n\tlinux-kernel@vger.kernel.org, Tomi Valkeinen <tomi.valkeinen@ti.com>, \n\tSakari Ailus <sakari.ailus@iki.fi>, Laurent Pinchart\n\t<laurent.pinchart@ideasonboard.com>, =?utf-8?q?Beno=C3=AEt_Cousson?=\n\t<bcousson@baylibre.com>,  linux-arm-kernel@lists.infradead.org",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "base64",
        "Sender": "\"linux-arm-kernel\" <linux-arm-kernel-bounces@lists.infradead.org>",
        "Errors-To": "linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org",
        "List-Id": "linux-imx-kernel.lists.patchwork.ozlabs.org"
    },
    "content": "We can handle the sysc interconnect target module in a generic way\nfor many TI SoCs. Initially let's just enable runtime PM with\nautosuspend, and probe the children. This can already be used for\nidling interconnect target modules that don't have any device driver\navailable for the child devices.\n\nFor now, the \"ti,hwmods\" custom binding is still required. That will\nbe eventually deprecated in later patches. And more features will be\nadded, such as parsing for sysc capabilities so we can continue\nremoving the legacy platform data.\n\nCc: Benoît Cousson <bcousson@baylibre.com>\nCc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>\nCc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\nCc: Nishanth Menon <nm@ti.com>\nCc: Matthijs van Duin <matthijsvanduin@gmail.com>\nCc: Paul Walmsley <paul@pwsan.com>\nCc: Peter Ujfalusi <peter.ujfalusi@ti.com>\nCc: Sakari Ailus <sakari.ailus@iki.fi>\nCc: Tero Kristo <t-kristo@ti.com>\nCc: Tomi Valkeinen <tomi.valkeinen@ti.com>\nCc: linux-kernel@vger.kernel.org\nSigned-off-by: Tony Lindgren <tony@atomide.com>\n---\n arch/arm/mach-omap2/Kconfig |   1 +\n drivers/bus/Kconfig         |   7 +\n drivers/bus/Makefile        |   1 +\n drivers/bus/ti-sysc.c       | 571 ++++++++++++++++++++++++++++++++++++++++++++\n 4 files changed, 580 insertions(+)\n create mode 100644 drivers/bus/ti-sysc.c",
    "diff": "diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig\n--- a/arch/arm/mach-omap2/Kconfig\n+++ b/arch/arm/mach-omap2/Kconfig\n@@ -104,6 +104,7 @@ config ARCH_OMAP2PLUS\n \tselect OMAP_GPMC\n \tselect PINCTRL\n \tselect SOC_BUS\n+\tselect TI_SYSC\n \tselect OMAP_IRQCHIP\n \tselect CLKSRC_TI_32K\n \thelp\ndiff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig\n--- a/drivers/bus/Kconfig\n+++ b/drivers/bus/Kconfig\n@@ -157,6 +157,13 @@ config TEGRA_GMI\n \t  Driver for the Tegra Generic Memory Interface bus which can be used\n \t  to attach devices such as NOR, UART, FPGA and more.\n \n+config TI_SYSC\n+\tbool \"TI sysc interconnect target module driver\"\n+\tdepends on ARCH_OMAP2PLUS\n+\thelp\n+\t  Generic driver for Texas Instruments interconnect target module\n+\t  found on many TI SoCs.\n+\n config UNIPHIER_SYSTEM_BUS\n \ttristate \"UniPhier System Bus driver\"\n \tdepends on ARCH_UNIPHIER && OF\ndiff --git a/drivers/bus/Makefile b/drivers/bus/Makefile\n--- a/drivers/bus/Makefile\n+++ b/drivers/bus/Makefile\n@@ -20,6 +20,7 @@ obj-$(CONFIG_SUNXI_RSB)\t\t+= sunxi-rsb.o\n obj-$(CONFIG_SIMPLE_PM_BUS)\t+= simple-pm-bus.o\n obj-$(CONFIG_TEGRA_ACONNECT)\t+= tegra-aconnect.o\n obj-$(CONFIG_TEGRA_GMI)\t\t+= tegra-gmi.o\n+obj-$(CONFIG_TI_SYSC)\t\t+= ti-sysc.o\n obj-$(CONFIG_UNIPHIER_SYSTEM_BUS)\t+= uniphier-system-bus.o\n obj-$(CONFIG_VEXPRESS_CONFIG)\t+= vexpress-config.o\n \ndiff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c\nnew file mode 100644\n--- /dev/null\n+++ b/drivers/bus/ti-sysc.c\n@@ -0,0 +1,571 @@\n+/*\n+ * ti-sysc.c - Texas Instruments sysc interconnect target driver\n+ *\n+ * This program is free software; you can redistribute it and/or modify\n+ * it under the terms of the GNU General Public License version 2 as\n+ * published by the Free Software Foundation.\n+ *\n+ * This program is distributed \"as is\" WITHOUT ANY WARRANTY of any\n+ * kind, whether express or implied; without even the implied warranty\n+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+ * GNU General Public License for more details.\n+ */\n+\n+#include <linux/io.h>\n+#include <linux/clk.h>\n+#include <linux/module.h>\n+#include <linux/platform_device.h>\n+#include <linux/pm_runtime.h>\n+#include <linux/of_address.h>\n+#include <linux/of_platform.h>\n+\n+enum sysc_registers {\n+\tSYSC_REVISION,\n+\tSYSC_SYSCONFIG,\n+\tSYSC_SYSSTATUS,\n+\tSYSC_MAX_REGS,\n+};\n+\n+static const char * const reg_names[] = { \"rev\", \"sysc\", \"syss\", };\n+\n+/* Adding support for omap2 and 3 will need additional fck and ick */\n+enum sysc_clocks {\n+\tSYSC_CLKCTRL,\n+\tSYSC_MAX_CLOCKS,\n+};\n+\n+static const char * const clock_names[] = { \"clkctrl\", };\n+\n+/**\n+ * struct sysc - TI sysc interconnect target module registers and capabilities\n+ * @dev: struct device pointer\n+ * @module_pa: physical address of the interconnect target module\n+ * @module_size: size of the interconnect target module\n+ * @module_va: virtual address of the interconnect target module\n+ * @offsets: register offsets from module base\n+ * @clocks: clocks used by the interconnect target module\n+ * @legacy_mode: configured for legacy mode if set\n+ */\n+struct sysc {\n+\tstruct device *dev;\n+\tu64 module_pa;\n+\tu32 module_size;\n+\tvoid __iomem *module_va;\n+\tint offsets[SYSC_MAX_REGS];\n+\tstruct clk *clocks[SYSC_MAX_CLOCKS];\n+\tconst char *legacy_mode;\n+};\n+\n+static u32 sysc_read_revision(struct sysc *ddata)\n+{\n+\treturn readl_relaxed(ddata->module_va +\n+\t\t\t     ddata->offsets[SYSC_REVISION]);\n+}\n+\n+static int sysc_get_one_clock(struct sysc *ddata,\n+\t\t\t      enum sysc_clocks index)\n+{\n+\tconst char *name;\n+\tint error;\n+\n+\tswitch (index) {\n+\tcase SYSC_CLKCTRL:\n+\t\tname = clock_names[index];\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tddata->clocks[index] = devm_clk_get(ddata->dev, name);\n+\tif (IS_ERR(ddata->clocks[index])) {\n+\t\tif (PTR_ERR(ddata->clocks[index]) == -ENOENT)\n+\t\t\treturn 0;\n+\n+\t\tdev_err(ddata->dev, \"clock get error for %s: %li\\n\",\n+\t\t\tname, PTR_ERR(ddata->clocks[index]));\n+\n+\t\treturn PTR_ERR(ddata->clocks[index]);\n+\t}\n+\n+\terror = clk_prepare(ddata->clocks[index]);\n+\tif (error) {\n+\t\tdev_err(ddata->dev, \"clock prepare error for %s: %i\\n\",\n+\t\t\tname, error);\n+\n+\t\treturn error;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int sysc_get_clocks(struct sysc *ddata)\n+{\n+\tint i, error;\n+\n+\tif (ddata->legacy_mode)\n+\t\treturn 0;\n+\n+\tfor (i = 0; i < SYSC_MAX_CLOCKS; i++) {\n+\t\terror = sysc_get_one_clock(ddata, i);\n+\t\tif (error && error != -ENOENT)\n+\t\t\treturn error;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * sysc_parse_and_check_child_range - parses module IO region from ranges\n+ * @ddata: device driver data\n+ *\n+ * In general we only need rev, syss, and sysc registers and not the whole\n+ * module range. But we do want the offsets for these registers from the\n+ * module base. This allows us to check them against the legacy hwmod\n+ * platform data. Let's also check the ranges are configured properly.\n+ */\n+static int sysc_parse_and_check_child_range(struct sysc *ddata)\n+{\n+\tstruct device_node *np = ddata->dev->of_node;\n+\tconst __be32 *ranges;\n+\tu32 nr_addr, nr_size;\n+\tint len, error;\n+\n+\tranges = of_get_property(np, \"ranges\", &len);\n+\tif (!ranges) {\n+\t\tdev_err(ddata->dev, \"missing ranges for %pOF\\n\", np);\n+\n+\t\treturn -ENOENT;\n+\t}\n+\n+\tlen /= sizeof(*ranges);\n+\n+\tif (len < 3) {\n+\t\tdev_err(ddata->dev, \"incomplete ranges for %pOF\\n\", np);\n+\n+\t\treturn -EINVAL;\n+\t}\n+\n+\terror = of_property_read_u32(np, \"#address-cells\", &nr_addr);\n+\tif (error)\n+\t\treturn -ENOENT;\n+\n+\terror = of_property_read_u32(np, \"#size-cells\", &nr_size);\n+\tif (error)\n+\t\treturn -ENOENT;\n+\n+\tif (nr_addr != 1 || nr_size != 1) {\n+\t\tdev_err(ddata->dev, \"invalid ranges for %pOF\\n\", np);\n+\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tranges++;\n+\tddata->module_pa = of_translate_address(np, ranges++);\n+\tddata->module_size = be32_to_cpup(ranges);\n+\n+\tdev_dbg(ddata->dev, \"interconnect target 0x%llx size 0x%x for %pOF\\n\",\n+\t\tddata->module_pa, ddata->module_size, np);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * sysc_check_one_child - check child configuration\n+ * @ddata: device driver data\n+ * @np: child device node\n+ *\n+ * Let's avoid messy situations where we have new interconnect target\n+ * node but children have \"ti,hwmods\" or the clkctrl clock. These\n+ * belong to the interconnect target node and are managed by this\n+ * driver.\n+ */\n+static int sysc_check_one_child(struct sysc *ddata,\n+\t\t\t\tstruct device_node *np)\n+{\n+\tstruct property *prop;\n+\tconst char *name;\n+\n+\tname = of_get_property(np, \"ti,hwmods\", NULL);\n+\tif (name) {\n+\t\tdev_err(ddata->dev, \"bogus child ti,hwmods property\");\n+\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tof_property_for_each_string(np, \"clocks\", prop, name)\n+\t\tif (!strncmp(\"clkctrl\", name, 7))\n+\t\t\tbreak;\n+\n+\tif (name) {\n+\t\tdev_err(ddata->dev, \"bogus child clkctrl property\");\n+\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int sysc_check_children(struct sysc *ddata)\n+{\n+\tstruct device_node *child;\n+\tint error;\n+\n+\tfor_each_child_of_node(ddata->dev->of_node, child) {\n+\t\terror = sysc_check_one_child(ddata, child);\n+\t\tif (error)\n+\t\t\treturn error;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * sysc_parse_one - parses the interconnect target module registers\n+ * @ddata: device driver data\n+ * @reg: register to parse\n+ */\n+static int sysc_parse_one(struct sysc *ddata, enum sysc_registers reg)\n+{\n+\tstruct resource *res;\n+\tconst char *name;\n+\n+\tswitch (reg) {\n+\tcase SYSC_REVISION:\n+\tcase SYSC_SYSCONFIG:\n+\tcase SYSC_SYSSTATUS:\n+\t\tname = reg_names[reg];\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tres = platform_get_resource_byname(to_platform_device(ddata->dev),\n+\t\t\t\t\t   IORESOURCE_MEM, name);\n+\tif (!res) {\n+\t\tdev_dbg(ddata->dev, \"has no %s register\\n\", name);\n+\t\tddata->offsets[reg] = -ENODEV;\n+\n+\t\treturn 0;\n+\t}\n+\n+\tddata->offsets[reg] = res->start - ddata->module_pa;\n+\n+\treturn 0;\n+}\n+\n+static int sysc_parse_registers(struct sysc *ddata)\n+{\n+\tint i, error;\n+\n+\tfor (i = 0; i < SYSC_MAX_REGS; i++) {\n+\t\terror = sysc_parse_one(ddata, i);\n+\t\tif (error)\n+\t\t\treturn error;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * sysc_check_registers - check for misconfigured register overlaps\n+ * @ddata: device driver data\n+ */\n+static int sysc_check_registers(struct sysc *ddata)\n+{\n+\tint i, j, nr_regs = 0, nr_matches = 0;\n+\n+\tfor (i = 0; i < SYSC_MAX_REGS; i++) {\n+\t\tif (ddata->offsets[i] < 0)\n+\t\t\tcontinue;\n+\n+\t\tif (ddata->offsets[i] > (ddata->module_size - 4)) {\n+\t\t\tdev_err(ddata->dev, \"register outside module range\");\n+\n+\t\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tfor (j = 0; j < SYSC_MAX_REGS; j++) {\n+\t\t\tif (ddata->offsets[j] < 0)\n+\t\t\t\tcontinue;\n+\n+\t\t\tif (ddata->offsets[i] == ddata->offsets[j])\n+\t\t\t\tnr_matches++;\n+\t\t}\n+\t\tnr_regs++;\n+\t}\n+\n+\tif (nr_regs < 1) {\n+\t\tdev_err(ddata->dev, \"missing registers\\n\");\n+\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (nr_matches > nr_regs) {\n+\t\tdev_err(ddata->dev, \"overlapping registers: (%i/%i)\",\n+\t\t\tnr_regs, nr_matches);\n+\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * syc_ioremap - ioremap register space for the interconnect target module\n+ * @ddata: deviec driver data\n+ *\n+ * Note that the interconnect target module registers can be anywhere\n+ * within the first child device address space. For example, SGX has\n+ * them at offset 0x1fc00 in the 32MB module address space. We just\n+ * what we need around the interconnect target module registers.\n+ */\n+static int sysc_ioremap(struct sysc *ddata)\n+{\n+\tu32 size = 0;\n+\n+\tif (ddata->offsets[SYSC_SYSSTATUS] >= 0)\n+\t\tsize = ddata->offsets[SYSC_SYSSTATUS];\n+\telse if (ddata->offsets[SYSC_SYSCONFIG] >= 0)\n+\t\tsize = ddata->offsets[SYSC_SYSCONFIG];\n+\telse if (ddata->offsets[SYSC_REVISION] >= 0)\n+\t\tsize = ddata->offsets[SYSC_REVISION];\n+\telse\n+\t\treturn -EINVAL;\n+\n+\tsize &= 0xfff00;\n+\tsize += SZ_256;\n+\n+\tddata->module_va = devm_ioremap(ddata->dev,\n+\t\t\t\t\tddata->module_pa,\n+\t\t\t\t\tsize);\n+\tif (!ddata->module_va)\n+\t\treturn -EIO;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * sysc_map_and_check_registers - ioremap and check device registers\n+ * @ddata: device driver data\n+ */\n+static int sysc_map_and_check_registers(struct sysc *ddata)\n+{\n+\tint error;\n+\n+\terror = sysc_parse_and_check_child_range(ddata);\n+\tif (error)\n+\t\treturn error;\n+\n+\terror = sysc_check_children(ddata);\n+\tif (error)\n+\t\treturn error;\n+\n+\terror = sysc_parse_registers(ddata);\n+\tif (error)\n+\t\treturn error;\n+\n+\terror = sysc_ioremap(ddata);\n+\tif (error)\n+\t\treturn error;\n+\n+\terror = sysc_check_registers(ddata);\n+\tif (error)\n+\t\treturn error;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * sysc_show_rev - read and show interconnect target module revision\n+ * @bufp: buffer to print the information to\n+ * @ddata: device driver data\n+ */\n+static int sysc_show_rev(char *bufp, struct sysc *ddata)\n+{\n+\tint error, len;\n+\n+\tif (ddata->offsets[SYSC_REVISION] < 0)\n+\t\treturn sprintf(bufp, \":NA\");\n+\n+\terror = pm_runtime_get_sync(ddata->dev);\n+\tif (error < 0) {\n+\t\tpm_runtime_put_noidle(ddata->dev);\n+\n+\t\treturn 0;\n+\t}\n+\n+\tlen = sprintf(bufp, \":%08x\", sysc_read_revision(ddata));\n+\n+\tpm_runtime_mark_last_busy(ddata->dev);\n+\tpm_runtime_put_autosuspend(ddata->dev);\n+\n+\treturn len;\n+}\n+\n+static int sysc_show_reg(struct sysc *ddata,\n+\t\t\t char *bufp, enum sysc_registers reg)\n+{\n+\tif (ddata->offsets[reg] < 0)\n+\t\treturn sprintf(bufp, \":NA\");\n+\n+\treturn sprintf(bufp, \":%x\", ddata->offsets[reg]);\n+}\n+\n+/**\n+ * sysc_show_registers - show information about interconnect target module\n+ * @ddata: device driver data\n+ */\n+static void sysc_show_registers(struct sysc *ddata)\n+{\n+\tchar buf[128];\n+\tchar *bufp = buf;\n+\tint i;\n+\n+\tfor (i = 0; i < SYSC_MAX_REGS; i++)\n+\t\tbufp += sysc_show_reg(ddata, bufp, i);\n+\n+\tbufp += sysc_show_rev(bufp, ddata);\n+\n+\tdev_dbg(ddata->dev, \"%llx:%x%s\\n\",\n+\t\tddata->module_pa, ddata->module_size,\n+\t\tbuf);\n+}\n+\n+static int sysc_runtime_suspend(struct device *dev)\n+{\n+\tstruct sysc *ddata;\n+\tint i;\n+\n+\tddata = dev_get_drvdata(dev);\n+\n+\tif (ddata->legacy_mode)\n+\t\treturn 0;\n+\n+\tfor (i = 0; i < SYSC_MAX_CLOCKS; i++) {\n+\t\tif (IS_ERR_OR_NULL(ddata->clocks[i]))\n+\t\t\tcontinue;\n+\t\tclk_disable(ddata->clocks[i]);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int sysc_runtime_resume(struct device *dev)\n+{\n+\tstruct sysc *ddata;\n+\tint i, error;\n+\n+\tddata = dev_get_drvdata(dev);\n+\n+\tif (ddata->legacy_mode)\n+\t\treturn 0;\n+\n+\tfor (i = 0; i < SYSC_MAX_CLOCKS; i++) {\n+\t\tif (IS_ERR_OR_NULL(ddata->clocks[i]))\n+\t\t\tcontinue;\n+\t\terror = clk_enable(ddata->clocks[i]);\n+\t\tif (error)\n+\t\t\treturn error;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static const struct dev_pm_ops sysc_pm_ops = {\n+\tSET_RUNTIME_PM_OPS(sysc_runtime_suspend,\n+\t\t\t   sysc_runtime_resume,\n+\t\t\t   NULL)\n+};\n+\n+static void sysc_unprepare(struct sysc *ddata)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < SYSC_MAX_CLOCKS; i++) {\n+\t\tif (!IS_ERR_OR_NULL(ddata->clocks[i]))\n+\t\t\tclk_unprepare(ddata->clocks[i]);\n+\t}\n+}\n+\n+static int sysc_probe(struct platform_device *pdev)\n+{\n+\tstruct device_node *np = pdev->dev.of_node;\n+\tstruct sysc *ddata;\n+\tint error;\n+\n+\tddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);\n+\tif (!ddata)\n+\t\treturn -ENOMEM;\n+\n+\tddata->dev = &pdev->dev;\n+\tddata->legacy_mode = of_get_property(np, \"ti,hwmods\", NULL);\n+\n+\terror = sysc_get_clocks(ddata);\n+\tif (error)\n+\t\treturn error;\n+\n+\terror = sysc_map_and_check_registers(ddata);\n+\tif (error)\n+\t\tgoto unprepare;\n+\n+\tplatform_set_drvdata(pdev, ddata);\n+\n+\tpm_runtime_enable(ddata->dev);\n+\terror = pm_runtime_get_sync(ddata->dev);\n+\tif (error < 0) {\n+\t\tpm_runtime_put_noidle(ddata->dev);\n+\t\tpm_runtime_disable(ddata->dev);\n+\t\tgoto unprepare;\n+\t}\n+\n+\tpm_runtime_use_autosuspend(ddata->dev);\n+\n+\tsysc_show_registers(ddata);\n+\n+\terror = of_platform_populate(ddata->dev->of_node,\n+\t\t\t\t     NULL, NULL, ddata->dev);\n+\tif (error)\n+\t\tgoto err;\n+\n+\tpm_runtime_mark_last_busy(ddata->dev);\n+\tpm_runtime_put_autosuspend(ddata->dev);\n+\n+\treturn 0;\n+\n+err:\n+\tpm_runtime_dont_use_autosuspend(&pdev->dev);\n+\tpm_runtime_put_sync(&pdev->dev);\n+\tpm_runtime_disable(&pdev->dev);\n+unprepare:\n+\tsysc_unprepare(ddata);\n+\n+\treturn error;\n+}\n+\n+static const struct of_device_id sysc_match[] = {\n+\t{ .compatible = \"ti,sysc-type1\" },\n+\t{ .compatible = \"ti,sysc-type2\" },\n+\t{ .compatible = \"ti,sysc-type3\" },\n+\t{ .compatible = \"ti,sysc-omap3430-sr\" },\n+\t{ .compatible = \"ti,sysc-omap3630-sr\" },\n+\t{ .compatible = \"ti,sysc-omap4-sr\" },\n+\t{ .compatible = \"ti,sysc-omap3-sham\" },\n+\t{ .compatible = \"ti,sysc-omap-aes\" },\n+\t{ .compatible = \"ti,sysc-mcasp\" },\n+\t{ .compatible = \"ti,sysc-usb-host-fs\" },\n+\t{  },\n+};\n+MODULE_DEVICE_TABLE(of, sysc_match);\n+\n+static struct platform_driver sysc_driver = {\n+\t.probe\t\t= sysc_probe,\n+\t.driver         = {\n+\t\t.name   = \"ti-sysc\",\n+\t\t.of_match_table\t= sysc_match,\n+\t\t.pm = &sysc_pm_ops,\n+\t},\n+};\n+module_platform_driver(sysc_driver);\n+\n+MODULE_DESCRIPTION(\"TI sysc interconnect target driver\");\n+MODULE_LICENSE(\"GPL v2\");\n",
    "prefixes": [
        "07/10"
    ]
}