get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 808777,
    "url": "http://patchwork.ozlabs.org/api/patches/808777/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/openbmc/patch/1504281966-6199-2-git-send-email-oleksandrs@mellanox.com/",
    "project": {
        "id": 56,
        "url": "http://patchwork.ozlabs.org/api/projects/56/?format=api",
        "name": "OpenBMC development",
        "link_name": "openbmc",
        "list_id": "openbmc.lists.ozlabs.org",
        "list_email": "openbmc@lists.ozlabs.org",
        "web_url": "http://github.com/openbmc/",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<1504281966-6199-2-git-send-email-oleksandrs@mellanox.com>",
    "list_archive_url": null,
    "date": "2017-09-01T16:06:03",
    "name": "[v7,1/4] drivers: jtag: Add JTAG core driver",
    "commit_ref": null,
    "pull_url": null,
    "state": "not-applicable",
    "archived": true,
    "hash": "a84a667e83e4cf75cf2f4aefd36f55b469bebcf6",
    "submitter": {
        "id": 72099,
        "url": "http://patchwork.ozlabs.org/api/people/72099/?format=api",
        "name": "Oleksandr Shamray",
        "email": "oleksandrs@mellanox.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/openbmc/patch/1504281966-6199-2-git-send-email-oleksandrs@mellanox.com/mbox/",
    "series": [
        {
            "id": 1060,
            "url": "http://patchwork.ozlabs.org/api/series/1060/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/openbmc/list/?series=1060",
            "date": "2017-09-01T16:06:02",
            "name": "JTAG driver introduction",
            "version": 7,
            "mbox": "http://patchwork.ozlabs.org/series/1060/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/808777/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/808777/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "openbmc@lists.ozlabs.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@bilbo.ozlabs.org",
            "openbmc@lists.ozlabs.org"
        ],
        "Received": [
            "from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\t(using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xkPJd1y9Sz9t2x\n\tfor <incoming@patchwork.ozlabs.org>;\n\tSat,  2 Sep 2017 02:07:13 +1000 (AEST)",
            "from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 3xkPJc622jzDqkQ\n\tfor <incoming@patchwork.ozlabs.org>;\n\tSat,  2 Sep 2017 02:07:12 +1000 (AEST)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 3xkPHv3rC3zDqZx\n\tfor <openbmc@lists.ozlabs.org>; Sat,  2 Sep 2017 02:06:34 +1000 (AEST)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n\toleksandrs@mellanox.com)\n\twith ESMTPS (AES256-SHA encrypted); 1 Sep 2017 19:06:26 +0300",
            "from r-vnc16.mtr.labs.mlnx (r-vnc16.mtr.labs.mlnx [10.208.0.16])\n\tby labmailer.mlnx (8.13.8/8.13.8) with ESMTP id v81G6P6P002351;\n\tFri, 1 Sep 2017 19:06:26 +0300"
        ],
        "From": "Oleksandr Shamray <oleksandrs@mellanox.com>",
        "To": "gregkh@linuxfoundation.org, arnd@arndb.de",
        "Subject": "[patch v7 1/4] drivers: jtag: Add JTAG core driver",
        "Date": "Fri,  1 Sep 2017 19:06:03 +0300",
        "Message-Id": "<1504281966-6199-2-git-send-email-oleksandrs@mellanox.com>",
        "X-Mailer": "git-send-email 1.7.1",
        "In-Reply-To": "<1504281966-6199-1-git-send-email-oleksandrs@mellanox.com>",
        "References": "<1504281966-6199-1-git-send-email-oleksandrs@mellanox.com>",
        "X-BeenThere": "openbmc@lists.ozlabs.org",
        "X-Mailman-Version": "2.1.23",
        "Precedence": "list",
        "List-Id": "Development list for OpenBMC <openbmc.lists.ozlabs.org>",
        "List-Unsubscribe": "<https://lists.ozlabs.org/options/openbmc>,\n\t<mailto:openbmc-request@lists.ozlabs.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.ozlabs.org/pipermail/openbmc/>",
        "List-Post": "<mailto:openbmc@lists.ozlabs.org>",
        "List-Help": "<mailto:openbmc-request@lists.ozlabs.org?subject=help>",
        "List-Subscribe": "<https://lists.ozlabs.org/listinfo/openbmc>,\n\t<mailto:openbmc-request@lists.ozlabs.org?subject=subscribe>",
        "Cc": "devicetree@vger.kernel.org, jiri@resnulli.us,\n\tsystem-sw-low-level@mellanox.com, linux-api@vger.kernel.org,\n\topenbmc@lists.ozlabs.org, linux-kernel@vger.kernel.org,\n\topenocd-devel-owner@lists.sourceforge.net, mec@shout.net,\n\tJiri Pirko <jiri@mellanox.com>, robh+dt@kernel.org,\n\tlinux-serial@vger.kernel.org, vadimp@maellanox.com,\n\tOleksandr Shamray <oleksandrs@mellanox.com>, tklauser@distanz.ch,\n\tmchehab@kernel.org, davem@davemloft.net,\n\tlinux-arm-kernel@lists.infradead.org",
        "Errors-To": "openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org",
        "Sender": "\"openbmc\"\n\t<openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org>"
    },
    "content": "Initial patch for JTAG friver\nJTAG class driver provide infrastructure to support hardware/software\nJTAG platform drivers. It provide user layer API interface for flashing\nand debugging external devices which equipped with JTAG interface\nusing standard transactions.\n\nDriver exposes set of IOCTL to user space for:\n- XFER:\n- SIR (Scan Instruction Register, IEEE 1149.1 Data Register scan);\n- SDR (Scan Data Register, IEEE 1149.1 Instruction Register scan);\n- RUNTEST (Forces the IEEE 1149.1 bus to a run state for a specified\n  number of clocks).\n- SIOCFREQ/GIOCFREQ for setting and reading JTAG frequency.\n\nDriver core provides set of internal APIs for allocation and\nregistration:\n- jtag_register;\n- jtag_unregister;\n- jtag_alloc;\n- jtag_free;\n\nPlatform driver on registration with jtag-core creates the next\nentry in dev folder:\n/dev/jtagX\n\nSigned-off-by: Oleksandr Shamray <oleksandrs@mellanox.com>\nSigned-off-by: Jiri Pirko <jiri@mellanox.com>\n---\nv6->v7\nNotifications from kbuild test robot <lkp@intel.com>\n- Remove include asm/types.h from jtag.h\n- Add include <linux/types.h> to jtag.c\n\nv5->v6\nv4->v5\n\nv3->v4\nComments pointed by Arnd Bergmann <arnd@arndb.de>\n- change transaction pointer tdio type  to __u64\n- change internal status type from enum to __u32\n- reorder jtag_xfer members to aviod the implied padding\n- add __packed attribute to jtag_xfer and jtag_run_test_idle\n\nv2->v3\nNotifications from kbuild test robot <lkp@intel.com>\n- Change include path to <linux/types.h> in jtag.h\n\nv1->v2\nComments pointed by Greg KH <gregkh@linuxfoundation.org>\n- Change license type from GPLv2/BSD to GPLv2\n- Change type of variables which crossed user/kernel to __type\n- Remove \"default n\" from Kconfig\n\nComments pointed by Andrew Lunn <andrew@lunn.ch>\n- Change list_add_tail in jtag_unregister to list_del\n\nComments pointed by Neil Armstrong <narmstrong@baylibre.com>\n- Add SPDX-License-Identifier instead of license text\n\nComments pointed by Arnd Bergmann <arnd@arndb.de>\n- Change __copy_to_user to memdup_user\n- Change __put_user to put_user\n- Change type of variables to __type for compatible 32 and 64-bit systems\n- Add check for maximum xfer data size\n- Change lookup data mechanism to get jtag data from inode\n- Add .compat_ioctl to file ops\n- Add mem alignment for jtag priv data\n\nComments pointed by Tobias Klauser <tklauser@distanz.ch>\n- Change function names to avoid match with variable types\n- Fix description for jtag_ru_test_idle in uapi jtag.h\n- Fix misprints IDEL/IDLE, trough/through\n---\n Documentation/ioctl/ioctl-number.txt |    2 +\n MAINTAINERS                          |    8 +\n drivers/Kconfig                      |    2 +\n drivers/Makefile                     |    1 +\n drivers/jtag/Kconfig                 |   16 ++\n drivers/jtag/Makefile                |    1 +\n drivers/jtag/jtag.c                  |  312 ++++++++++++++++++++++++++++++++++\n include/linux/jtag.h                 |   48 +++++\n include/uapi/linux/jtag.h            |  111 ++++++++++++\n 9 files changed, 501 insertions(+), 0 deletions(-)\n create mode 100644 drivers/jtag/Kconfig\n create mode 100644 drivers/jtag/Makefile\n create mode 100644 drivers/jtag/jtag.c\n create mode 100644 include/linux/jtag.h\n create mode 100644 include/uapi/linux/jtag.h",
    "diff": "diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt\nindex 3e3fdae..1af2508 100644\n--- a/Documentation/ioctl/ioctl-number.txt\n+++ b/Documentation/ioctl/ioctl-number.txt\n@@ -321,6 +321,8 @@ Code  Seq#(hex)\tInclude File\t\tComments\n 0xB0\tall\tRATIO devices\t\tin development:\n \t\t\t\t\t<mailto:vgo@ratio.de>\n 0xB1\t00-1F\tPPPoX\t\t\t<mailto:mostrows@styx.uwaterloo.ca>\n+0xB2\t00-0f\tlinux/jtag.h\t\tJTAG driver\n+\t\t\t\t\t<mailto:oleksandrs@mellanox.com>\n 0xB3\t00\tlinux/mmc/ioctl.h\n 0xB4\t00-0F\tlinux/gpio.h\t\t<mailto:linux-gpio@vger.kernel.org>\n 0xB5\t00-0F\tuapi/linux/rpmsg.h\t<mailto:linux-remoteproc@vger.kernel.org>\ndiff --git a/MAINTAINERS b/MAINTAINERS\nindex 205d397..141aeaf 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -7292,6 +7292,14 @@ L:\tlinux-serial@vger.kernel.org\n S:\tMaintained\n F:\tdrivers/tty/serial/jsm/\n \n+JTAG SUBSYSTEM\n+M:\tOleksandr Shamray <oleksandrs@mellanox.com>\n+M:\tVadim Pasternak <vadimp@mellanox.com>\n+S:\tMaintained\n+F:\tinclude/linux/jtag.h\n+F:\tinclude/uapi/linux/jtag.h\n+F:\tdrivers/jtag/\n+\n K10TEMP HARDWARE MONITORING DRIVER\n M:\tClemens Ladisch <clemens@ladisch.de>\n L:\tlinux-hwmon@vger.kernel.org\ndiff --git a/drivers/Kconfig b/drivers/Kconfig\nindex 505c676..2214678 100644\n--- a/drivers/Kconfig\n+++ b/drivers/Kconfig\n@@ -208,4 +208,6 @@ source \"drivers/tee/Kconfig\"\n \n source \"drivers/mux/Kconfig\"\n \n+source \"drivers/jtag/Kconfig\"\n+\n endmenu\ndiff --git a/drivers/Makefile b/drivers/Makefile\nindex dfdcda0..6a2059b 100644\n--- a/drivers/Makefile\n+++ b/drivers/Makefile\n@@ -182,3 +182,4 @@ obj-$(CONFIG_FPGA)\t\t+= fpga/\n obj-$(CONFIG_FSI)\t\t+= fsi/\n obj-$(CONFIG_TEE)\t\t+= tee/\n obj-$(CONFIG_MULTIPLEXER)\t+= mux/\n+obj-$(CONFIG_JTAG)\t\t+= jtag/\ndiff --git a/drivers/jtag/Kconfig b/drivers/jtag/Kconfig\nnew file mode 100644\nindex 0000000..0fad1a3\n--- /dev/null\n+++ b/drivers/jtag/Kconfig\n@@ -0,0 +1,16 @@\n+menuconfig JTAG\n+\ttristate \"JTAG support\"\n+\t---help---\n+\t  This provides basic core functionality support for jtag class devices\n+\t  Hardware equipped with JTAG microcontroller which can be built\n+\t  on top of this drivers. Driver exposes the set of IOCTL to the\n+\t  user space for:\n+\t  SIR (Scan Instruction Register, IEEE 1149.1 Data Register scan);\n+\t  SDR (Scan Data Register, IEEE 1149.1 Instruction Register scan);\n+\t  RUNTEST (Forces IEEE 1149.1 bus to a run state for specified\n+\t  number of clocks).\n+\n+\t  If you want this support, you should say Y here.\n+\n+\t  To compile this driver as a module, choose M here: the module will\n+\t  be called jtag.\ndiff --git a/drivers/jtag/Makefile b/drivers/jtag/Makefile\nnew file mode 100644\nindex 0000000..af37493\n--- /dev/null\n+++ b/drivers/jtag/Makefile\n@@ -0,0 +1 @@\n+obj-$(CONFIG_JTAG)\t\t+= jtag.o\ndiff --git a/drivers/jtag/jtag.c b/drivers/jtag/jtag.c\nnew file mode 100644\nindex 0000000..f948d4c\n--- /dev/null\n+++ b/drivers/jtag/jtag.c\n@@ -0,0 +1,312 @@\n+/*\n+ * drivers/jtag/jtag.c\n+ *\n+ * Copyright (c) 2017 Mellanox Technologies. All rights reserved.\n+ * Copyright (c) 2017 Oleksandr Shamray <oleksandrs@mellanox.com>\n+ *\n+ * Released under the GPLv2 only.\n+ * SPDX-License-Identifier: GPL-2.0\n+ */\n+\n+#include <linux/cdev.h>\n+#include <linux/device.h>\n+#include <linux/jtag.h>\n+#include <linux/kernel.h>\n+#include <linux/list.h>\n+#include <linux/module.h>\n+#include <linux/rtnetlink.h>\n+#include <linux/spinlock.h>\n+#include <linux/types.h>\n+#include <uapi/linux/jtag.h>\n+\n+struct jtag {\n+\tstruct list_head list;\n+\tstruct device *dev;\n+\tstruct cdev cdev;\n+\tint id;\n+\tspinlock_t lock;\n+\tint open;\n+\tconst struct jtag_ops *ops;\n+\tunsigned long priv[0] __aligned(ARCH_DMA_MINALIGN);\n+};\n+\n+static dev_t jtag_devt;\n+static LIST_HEAD(jtag_list);\n+static DEFINE_MUTEX(jtag_mutex);\n+static DEFINE_IDA(jtag_ida);\n+\n+void *jtag_priv(struct jtag *jtag)\n+{\n+\treturn jtag->priv;\n+}\n+EXPORT_SYMBOL_GPL(jtag_priv);\n+\n+static __u64 jtag_copy_from_user(__u64 udata, unsigned long bit_size)\n+{\n+\tunsigned long size;\n+\tvoid *kdata;\n+\n+\tsize = DIV_ROUND_UP(bit_size, BITS_PER_BYTE);\n+\tkdata = memdup_user(u64_to_user_ptr(udata), size);\n+\n+\treturn (__u64)(uintptr_t)kdata;\n+}\n+\n+static unsigned long jtag_copy_to_user(__u64 udata, __u64 kdata,\n+\t\t\t\t       unsigned long bit_size)\n+{\n+\tunsigned long size;\n+\n+\tsize = DIV_ROUND_UP(bit_size, BITS_PER_BYTE);\n+\n+\treturn copy_to_user(u64_to_user_ptr(udata), jtag_u64_to_ptr(kdata),\n+\t\t\t    size);\n+}\n+\n+static struct class jtag_class = {\n+\t.name = \"jtag\",\n+\t.owner = THIS_MODULE,\n+};\n+\n+static int jtag_run_test_idle_op(struct jtag *jtag,\n+\t\t\t\t struct jtag_run_test_idle *idle)\n+{\n+\tif (jtag->ops->idle)\n+\t\treturn jtag->ops->idle(jtag, idle);\n+\telse\n+\t\treturn -EOPNOTSUPP;\n+}\n+\n+static int jtag_xfer_op(struct jtag *jtag, struct jtag_xfer *xfer)\n+{\n+\tif (jtag->ops->xfer)\n+\t\treturn jtag->ops->xfer(jtag, xfer);\n+\telse\n+\t\treturn -EOPNOTSUPP;\n+}\n+\n+static long jtag_ioctl(struct file *file, unsigned int cmd, unsigned long arg)\n+{\n+\tstruct jtag *jtag = file->private_data;\n+\t__u32 *uarg = (__u32 __user *)arg;\n+\tvoid  *varg = (void __user *)arg;\n+\tstruct jtag_run_test_idle idle;\n+\tstruct jtag_xfer xfer;\n+\t__u64 tdio_user;\n+\t__u32 value;\n+\tint err;\n+\n+\tswitch (cmd) {\n+\tcase JTAG_GIOCFREQ:\n+\t\tif (jtag->ops->freq_get)\n+\t\t\terr = jtag->ops->freq_get(jtag, &value);\n+\t\telse\n+\t\t\terr = -EOPNOTSUPP;\n+\t\tif (err)\n+\t\t\tbreak;\n+\n+\t\terr = put_user(value, uarg);\n+\t\tbreak;\n+\n+\tcase JTAG_SIOCFREQ:\n+\t\terr = __get_user(value, uarg);\n+\n+\t\tif (value == 0)\n+\t\t\terr = -EINVAL;\n+\t\tif (err)\n+\t\t\tbreak;\n+\n+\t\tif (jtag->ops->freq_set)\n+\t\t\terr = jtag->ops->freq_set(jtag, value);\n+\t\telse\n+\t\t\terr = -EOPNOTSUPP;\n+\t\tbreak;\n+\n+\tcase JTAG_IOCRUNTEST:\n+\t\tif (copy_from_user(&idle, varg,\n+\t\t\t\t   sizeof(struct jtag_run_test_idle)))\n+\t\t\treturn -ENOMEM;\n+\t\terr = jtag_run_test_idle_op(jtag, &idle);\n+\t\tbreak;\n+\n+\tcase JTAG_IOCXFER:\n+\t\tif (copy_from_user(&xfer, varg, sizeof(struct jtag_xfer)))\n+\t\t\treturn -EFAULT;\n+\n+\t\tif (xfer.length >= JTAG_MAX_XFER_DATA_LEN)\n+\t\t\treturn -EFAULT;\n+\n+\t\ttdio_user = xfer.tdio;\n+\t\txfer.tdio = jtag_copy_from_user(xfer.tdio, xfer.length);\n+\t\tif (!xfer.tdio)\n+\t\t\treturn -ENOMEM;\n+\n+\t\terr = jtag_xfer_op(jtag, &xfer);\n+\t\tif (jtag_copy_to_user(tdio_user, xfer.tdio, xfer.length)) {\n+\t\t\tkfree(jtag_u64_to_ptr(xfer.tdio));\n+\t\t\treturn -EFAULT;\n+\t\t}\n+\n+\t\tkfree(jtag_u64_to_ptr(xfer.tdio));\n+\t\txfer.tdio = tdio_user;\n+\t\tif (copy_to_user(varg, &xfer, sizeof(struct jtag_xfer)))\n+\t\t\treturn -EFAULT;\n+\t\tbreak;\n+\n+\tcase JTAG_GIOCSTATUS:\n+\t\tif (jtag->ops->status_get)\n+\t\t\terr = jtag->ops->status_get(jtag, &value);\n+\t\telse\n+\t\t\terr = -EOPNOTSUPP;\n+\t\tif (err)\n+\t\t\tbreak;\n+\n+\t\terr = put_user(value, uarg);\n+\t\tbreak;\n+\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+\treturn err;\n+}\n+\n+#ifdef CONFIG_COMPAT\n+static long jtag_ioctl_compat(struct file *file, unsigned int cmd,\n+\t\t\t      unsigned long arg)\n+{\n+\treturn jtag_ioctl(file, cmd, (unsigned long)compat_ptr(arg));\n+}\n+#endif\n+\n+static int jtag_open(struct inode *inode, struct file *file)\n+{\n+\tstruct jtag *jtag = container_of(inode->i_cdev, struct jtag, cdev);\n+\n+\tspin_lock(&jtag->lock);\n+\n+\tif (jtag->open) {\n+\t\tdev_info(NULL, \"jtag already opened\\n\");\n+\t\tspin_unlock(&jtag->lock);\n+\t\treturn -EBUSY;\n+\t}\n+\n+\tjtag->open++;\n+\tfile->private_data = jtag;\n+\tspin_unlock(&jtag->lock);\n+\treturn 0;\n+}\n+\n+static int jtag_release(struct inode *inode, struct file *file)\n+{\n+\tstruct jtag *jtag = file->private_data;\n+\n+\tspin_lock(&jtag->lock);\n+\tjtag->open--;\n+\tspin_unlock(&jtag->lock);\n+\treturn 0;\n+}\n+\n+static const struct file_operations jtag_fops = {\n+\t.owner\t\t= THIS_MODULE,\n+\t.open\t\t= jtag_open,\n+\t.release\t= jtag_release,\n+\t.llseek\t\t= noop_llseek,\n+\t.unlocked_ioctl = jtag_ioctl,\n+#ifdef CONFIG_COMPAT\n+\t.compat_ioctl\t= jtag_ioctl_compat,\n+#endif\n+};\n+\n+struct jtag *jtag_alloc(size_t priv_size, const struct jtag_ops *ops)\n+{\n+\tstruct jtag *jtag;\n+\n+\tjtag = kzalloc(sizeof(*jtag) + round_up(priv_size, ARCH_DMA_MINALIGN),\n+\t\t       GFP_KERNEL);\n+\tif (!jtag)\n+\t\treturn NULL;\n+\n+\tjtag->ops = ops;\n+\treturn jtag;\n+}\n+EXPORT_SYMBOL_GPL(jtag_alloc);\n+\n+void jtag_free(struct jtag *jtag)\n+{\n+\tkfree(jtag);\n+}\n+EXPORT_SYMBOL_GPL(jtag_free);\n+\n+int jtag_register(struct jtag *jtag)\n+{\n+\tint id;\n+\tint err;\n+\n+\tid = ida_simple_get(&jtag_ida, 0, 0, GFP_KERNEL);\n+\tif (id < 0)\n+\t\treturn id;\n+\n+\tjtag->id = id;\n+\tcdev_init(&jtag->cdev, &jtag_fops);\n+\tjtag->cdev.owner = THIS_MODULE;\n+\terr = cdev_add(&jtag->cdev, MKDEV(MAJOR(jtag_devt), jtag->id), 1);\n+\tif (err)\n+\t\tgoto err_cdev;\n+\n+\t/* Register this jtag device with the driver core */\n+\tjtag->dev = device_create(&jtag_class, NULL, MKDEV(MAJOR(jtag_devt),\n+\t\t\t\t\t\t\t   jtag->id),\n+\t\t\t\t  NULL, \"jtag%d\", jtag->id);\n+\tif (!jtag->dev)\n+\t\tgoto err_device_create;\n+\n+\tjtag->open = 0;\n+\tdev_set_drvdata(jtag->dev, jtag);\n+\tspin_lock_init(&jtag->lock);\n+\tmutex_lock(&jtag_mutex);\n+\tlist_add_tail(&jtag->list, &jtag_list);\n+\tmutex_unlock(&jtag_mutex);\n+\treturn err;\n+\n+err_device_create:\n+\tcdev_del(&jtag->cdev);\n+err_cdev:\n+\tida_simple_remove(&jtag_ida, id);\n+\treturn err;\n+}\n+EXPORT_SYMBOL_GPL(jtag_register);\n+\n+void jtag_unregister(struct jtag *jtag)\n+{\n+\tstruct device *dev = jtag->dev;\n+\n+\tmutex_lock(&jtag_mutex);\n+\tlist_del(&jtag->list);\n+\tmutex_unlock(&jtag_mutex);\n+\tcdev_del(&jtag->cdev);\n+\tdevice_unregister(dev);\n+\tida_simple_remove(&jtag_ida, jtag->id);\n+}\n+EXPORT_SYMBOL_GPL(jtag_unregister);\n+\n+static int __init jtag_init(void)\n+{\n+\tint err;\n+\n+\terr = alloc_chrdev_region(&jtag_devt, 0, 1, \"jtag\");\n+\tif (err)\n+\t\treturn err;\n+\treturn class_register(&jtag_class);\n+}\n+\n+static void __exit jtag_exit(void)\n+{\n+\tclass_unregister(&jtag_class);\n+}\n+\n+module_init(jtag_init);\n+module_exit(jtag_exit);\n+\n+MODULE_AUTHOR(\"Oleksandr Shamray <oleksandrs@mellanox.com>\");\n+MODULE_DESCRIPTION(\"Generic jtag support\");\n+MODULE_LICENSE(\"GPL v2\");\ndiff --git a/include/linux/jtag.h b/include/linux/jtag.h\nnew file mode 100644\nindex 0000000..f48ae9d\n--- /dev/null\n+++ b/include/linux/jtag.h\n@@ -0,0 +1,48 @@\n+/*\n+ * drivers/jtag/jtag.c\n+ *\n+ * Copyright (c) 2017 Mellanox Technologies. All rights reserved.\n+ * Copyright (c) 2017 Oleksandr Shamray <oleksandrs@mellanox.com>\n+ *\n+ * Released under the GPLv2 only.\n+ * SPDX-License-Identifier: GPL-2.0\n+ */\n+\n+#ifndef __JTAG_H\n+#define __JTAG_H\n+\n+#include <uapi/linux/jtag.h>\n+\n+#ifndef ARCH_DMA_MINALIGN\n+#define ARCH_DMA_MINALIGN 1\n+#endif\n+\n+#define jtag_u64_to_ptr(arg) ((void *)(uintptr_t)arg)\n+\n+#define JTAG_MAX_XFER_DATA_LEN 65535\n+\n+struct jtag;\n+/**\n+ * struct jtag_ops - callbacks for jtag control functions:\n+ *\n+ * @freq_get: get frequency function. Filled by device driver\n+ * @freq_set: set frequency function. Filled by device driver\n+ * @status_get: set status function. Filled by device driver\n+ * @idle: set JTAG to idle state function. Filled by device driver\n+ * @xfer: send JTAG xfer function. Filled by device driver\n+ */\n+struct jtag_ops {\n+\tint (*freq_get)(struct jtag *jtag, __u32 *freq);\n+\tint (*freq_set)(struct jtag *jtag, __u32 freq);\n+\tint (*status_get)(struct jtag *jtag, __u32 *state);\n+\tint (*idle)(struct jtag *jtag, struct jtag_run_test_idle *idle);\n+\tint (*xfer)(struct jtag *jtag, struct jtag_xfer *xfer);\n+};\n+\n+void *jtag_priv(struct jtag *jtag);\n+int jtag_register(struct jtag *jtag);\n+void jtag_unregister(struct jtag *jtag);\n+struct jtag *jtag_alloc(size_t priv_size, const struct jtag_ops *ops);\n+void jtag_free(struct jtag *jtag);\n+\n+#endif /* __JTAG_H */\ndiff --git a/include/uapi/linux/jtag.h b/include/uapi/linux/jtag.h\nnew file mode 100644\nindex 0000000..af22ea6\n--- /dev/null\n+++ b/include/uapi/linux/jtag.h\n@@ -0,0 +1,111 @@\n+/*\n+ * JTAG class driver\n+ *\n+ * Copyright (c) 2017 Mellanox Technologies. All rights reserved.\n+ * Copyright (c) 2017 Oleksandr Shamray <oleksandrs@mellanox.com>\n+ *\n+ * Released under the GPLv2/BSD.\n+ * SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause\n+ */\n+\n+#ifndef __UAPI_LINUX_JTAG_H\n+#define __UAPI_LINUX_JTAG_H\n+\n+/**\n+ * enum jtag_xfer_mode:\n+ *\n+ * @JTAG_XFER_HW_MODE: hardware mode transfer\n+ * @JTAG_XFER_SW_MODE: software mode transfer\n+ */\n+enum jtag_xfer_mode {\n+\tJTAG_XFER_HW_MODE,\n+\tJTAG_XFER_SW_MODE,\n+};\n+\n+/**\n+ * enum jtag_endstate:\n+ *\n+ * @JTAG_STATE_IDLE: JTAG state machine IDLE state\n+ * @JTAG_STATE_PAUSEIR: JTAG state machine PAUSE_IR state\n+ * @JTAG_STATE_PAUSEDR: JTAG state machine PAUSE_DR state\n+ */\n+enum jtag_endstate {\n+\tJTAG_STATE_IDLE,\n+\tJTAG_STATE_PAUSEIR,\n+\tJTAG_STATE_PAUSEDR,\n+};\n+\n+/**\n+ * enum jtag_xfer_type:\n+ *\n+ * @JTAG_SIR_XFER: SIR transfer\n+ * @JTAG_SDR_XFER: SDR transfer\n+ */\n+enum jtag_xfer_type {\n+\tJTAG_SIR_XFER,\n+\tJTAG_SDR_XFER,\n+};\n+\n+/**\n+ * enum jtag_xfer_direction:\n+ *\n+ * @JTAG_READ_XFER: read transfer\n+ * @JTAG_WRITE_XFER: write transfer\n+ */\n+enum jtag_xfer_direction {\n+\tJTAG_READ_XFER,\n+\tJTAG_WRITE_XFER,\n+};\n+\n+/**\n+ * struct jtag_run_test_idle - forces JTAG state machine to\n+ * RUN_TEST/IDLE state\n+ *\n+ * @mode: access mode\n+ * @reset: 0 - run IDLE/PAUSE from current state\n+ *         1 - go through TEST_LOGIC/RESET state before  IDLE/PAUSE\n+ * @end: completion flag\n+ * @tck: clock counter\n+ *\n+ * Structure represents interface to JTAG device for jtag idle\n+ * execution.\n+ */\n+struct jtag_run_test_idle {\n+\t__u8\tmode;\n+\t__u8\treset;\n+\t__u8\tendstate;\n+\t__u8\ttck;\n+};\n+\n+/**\n+ * struct jtag_xfer - jtag xfer:\n+ *\n+ * @mode: access mode\n+ * @type: transfer type\n+ * @direction: xfer direction\n+ * @length: xfer bits len\n+ * @tdio : xfer data array\n+ * @endir: xfer end state\n+ *\n+ * Structure represents interface to Aspeed JTAG device for jtag sdr xfer\n+ * execution.\n+ */\n+struct jtag_xfer {\n+\t__u8\tmode;\n+\t__u8\ttype;\n+\t__u8\tdirection;\n+\t__u8\tendstate;\n+\t__u32\tlength;\n+\t__u64\ttdio;\n+};\n+\n+#define __JTAG_IOCTL_MAGIC\t0xb2\n+\n+#define JTAG_IOCRUNTEST\t_IOW(__JTAG_IOCTL_MAGIC, 0,\\\n+\t\t\t     struct jtag_run_test_idle)\n+#define JTAG_SIOCFREQ\t_IOW(__JTAG_IOCTL_MAGIC, 1, unsigned int)\n+#define JTAG_GIOCFREQ\t_IOR(__JTAG_IOCTL_MAGIC, 2, unsigned int)\n+#define JTAG_IOCXFER\t_IOWR(__JTAG_IOCTL_MAGIC, 3, struct jtag_xfer)\n+#define JTAG_GIOCSTATUS _IOWR(__JTAG_IOCTL_MAGIC, 4, enum jtag_endstate)\n+\n+#endif /* __UAPI_LINUX_JTAG_H */\n",
    "prefixes": [
        "v7",
        "1/4"
    ]
}