aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-4.4/7197-staging-fsl-mc-Management-Complex-restool-driver.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-4.4/7197-staging-fsl-mc-Management-Complex-restool-driver.patch')
-rw-r--r--target/linux/layerscape/patches-4.4/7197-staging-fsl-mc-Management-Complex-restool-driver.patch489
1 files changed, 0 insertions, 489 deletions
diff --git a/target/linux/layerscape/patches-4.4/7197-staging-fsl-mc-Management-Complex-restool-driver.patch b/target/linux/layerscape/patches-4.4/7197-staging-fsl-mc-Management-Complex-restool-driver.patch
deleted file mode 100644
index 2a5e5df2be..0000000000
--- a/target/linux/layerscape/patches-4.4/7197-staging-fsl-mc-Management-Complex-restool-driver.patch
+++ /dev/null
@@ -1,489 +0,0 @@
-From fb4881d149742e4c5595aca8bf86c99d2ea155ad Mon Sep 17 00:00:00 2001
-From: Lijun Pan <Lijun.Pan@freescale.com>
-Date: Mon, 8 Feb 2016 17:40:18 -0600
-Subject: [PATCH 197/226] staging: fsl-mc: Management Complex restool driver
-
-The kernel support for the restool (a user space resource management
-tool) is a driver for the /dev/dprc.N device file.
-Its purpose is to provide an ioctl interface,
-which the restool uses to interact with the MC bus driver
-and with the MC firmware.
-We allocate a dpmcp at driver initialization,
-and keep that dpmcp until driver exit.
-We use that dpmcp by default.
-If that dpmcp is in use, we create another portal at run time
-and destroy the newly created portal after use.
-The ioctl RESTOOL_SEND_MC_COMMAND sends user space command to fsl-mc
-bus and utilizes the fsl-mc bus to communicate with MC firmware.
-The ioctl RESTOOL_DPRC_SYNC request the mc-bus launch
-objects scan under root dprc.
-In order to support multiple root dprc, we utilize the bus notify
-mechanism to scan fsl_mc_bus_type for the newly added root dprc.
-After discovering the root dprc, it creates a miscdevice
-/dev/dprc.N to associate with this root dprc.
-
-Signed-off-by: Lijun Pan <Lijun.Pan@freescale.com>
-[Stuart: minor fix to resolve compile error]
-Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
----
- Documentation/ioctl/ioctl-number.txt | 1 +
- drivers/staging/fsl-mc/bus/Kconfig | 7 +-
- drivers/staging/fsl-mc/bus/Makefile | 3 +
- drivers/staging/fsl-mc/bus/mc-ioctl.h | 22 ++
- drivers/staging/fsl-mc/bus/mc-restool.c | 392 +++++++++++++++++++++++++++++++
- 5 files changed, 424 insertions(+), 1 deletion(-)
- create mode 100644 drivers/staging/fsl-mc/bus/mc-ioctl.h
- create mode 100644 drivers/staging/fsl-mc/bus/mc-restool.c
-
---- a/Documentation/ioctl/ioctl-number.txt
-+++ b/Documentation/ioctl/ioctl-number.txt
-@@ -170,6 +170,7 @@ Code Seq#(hex) Include File Comments
- 'R' 00-1F linux/random.h conflict!
- 'R' 01 linux/rfkill.h conflict!
- 'R' C0-DF net/bluetooth/rfcomm.h
-+'R' E0-EF drivers/staging/fsl-mc/bus/mc-ioctl.h
- 'S' all linux/cdrom.h conflict!
- 'S' 80-81 scsi/scsi_ioctl.h conflict!
- 'S' 82-FF scsi/scsi.h conflict!
---- a/drivers/staging/fsl-mc/bus/Kconfig
-+++ b/drivers/staging/fsl-mc/bus/Kconfig
-@@ -22,4 +22,9 @@ config FSL_MC_BUS
- Only enable this option when building the kernel for
- Freescale QorQIQ LS2xxxx SoCs.
-
--
-+config FSL_MC_RESTOOL
-+ tristate "Freescale Management Complex (MC) restool driver"
-+ depends on FSL_MC_BUS
-+ help
-+ Driver that provides kernel support for the Freescale Management
-+ Complex resource manager user-space tool.
---- a/drivers/staging/fsl-mc/bus/Makefile
-+++ b/drivers/staging/fsl-mc/bus/Makefile
-@@ -18,3 +18,6 @@ mc-bus-driver-objs := mc-bus.o \
- dpmcp.o \
- dpbp.o \
- dpcon.o
-+
-+# MC restool kernel support
-+obj-$(CONFIG_FSL_MC_RESTOOL) += mc-restool.o
---- /dev/null
-+++ b/drivers/staging/fsl-mc/bus/mc-ioctl.h
-@@ -0,0 +1,22 @@
-+/*
-+ * Freescale Management Complex (MC) ioclt interface
-+ *
-+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
-+ * Author: Lijun Pan <Lijun.Pan@freescale.com>
-+ *
-+ * This file is licensed under the terms of the GNU General Public
-+ * License version 2. This program is licensed "as is" without any
-+ * warranty of any kind, whether express or implied.
-+ */
-+#ifndef _FSL_MC_IOCTL_H_
-+#define _FSL_MC_IOCTL_H_
-+
-+#include <linux/ioctl.h>
-+#include "../include/mc-sys.h"
-+
-+#define RESTOOL_IOCTL_TYPE 'R'
-+
-+#define RESTOOL_SEND_MC_COMMAND \
-+ _IOWR(RESTOOL_IOCTL_TYPE, 0xE0, struct mc_command)
-+
-+#endif /* _FSL_MC_IOCTL_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl-mc/bus/mc-restool.c
-@@ -0,0 +1,392 @@
-+/*
-+ * Freescale Management Complex (MC) restool driver
-+ *
-+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
-+ * Author: Lijun Pan <Lijun.Pan@freescale.com>
-+ *
-+ * This file is licensed under the terms of the GNU General Public
-+ * License version 2. This program is licensed "as is" without any
-+ * warranty of any kind, whether express or implied.
-+ */
-+
-+#include "../include/mc-private.h"
-+#include <linux/module.h>
-+#include <linux/fs.h>
-+#include <linux/miscdevice.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/uaccess.h>
-+#include <linux/mutex.h>
-+#include <linux/platform_device.h>
-+#include "mc-ioctl.h"
-+#include "../include/mc-sys.h"
-+#include "../include/mc-cmd.h"
-+#include "../include/dpmng.h"
-+
-+/**
-+ * Maximum number of DPRCs that can be opened at the same time
-+ */
-+#define MAX_DPRC_HANDLES 64
-+
-+/**
-+ * restool_misc - information associated with the newly added miscdevice
-+ * @misc: newly created miscdevice associated with root dprc
-+ * @miscdevt: device id of this miscdevice
-+ * @list: a linked list node representing this miscdevcie
-+ * @static_mc_io: pointer to the static MC I/O object used by the restool
-+ * @dynamic_instance_count: number of dynamically created instances
-+ * @static_instance_in_use: static instance is in use or not
-+ * @mutex: mutex lock to serialze the open/release operations
-+ * @dev: root dprc associated with this miscdevice
-+ */
-+struct restool_misc {
-+ struct miscdevice misc;
-+ dev_t miscdevt;
-+ struct list_head list;
-+ struct fsl_mc_io *static_mc_io;
-+ u32 dynamic_instance_count;
-+ bool static_instance_in_use;
-+ struct mutex mutex; /* serialze the open/release operations */
-+ struct device *dev;
-+};
-+
-+/*
-+ * initialize a global list to link all
-+ * the miscdevice nodes (struct restool_misc)
-+ */
-+static LIST_HEAD(misc_list);
-+static DEFINE_MUTEX(misc_list_mutex);
-+
-+static int fsl_mc_restool_dev_open(struct inode *inode, struct file *filep)
-+{
-+ struct fsl_mc_device *root_mc_dev;
-+ int error;
-+ struct fsl_mc_io *dynamic_mc_io = NULL;
-+ struct restool_misc *restool_misc = NULL;
-+ struct restool_misc *restool_misc_cursor;
-+
-+ mutex_lock(&misc_list_mutex);
-+
-+ list_for_each_entry(restool_misc_cursor, &misc_list, list) {
-+ if (restool_misc_cursor->miscdevt == inode->i_rdev) {
-+ restool_misc = restool_misc_cursor;
-+ break;
-+ }
-+ }
-+
-+ mutex_unlock(&misc_list_mutex);
-+
-+ if (!restool_misc)
-+ return -EINVAL;
-+
-+ if (WARN_ON(!restool_misc->dev))
-+ return -EINVAL;
-+
-+ mutex_lock(&restool_misc->mutex);
-+
-+ if (!restool_misc->static_instance_in_use) {
-+ restool_misc->static_instance_in_use = true;
-+ filep->private_data = restool_misc->static_mc_io;
-+ } else {
-+ dynamic_mc_io = kzalloc(sizeof(*dynamic_mc_io), GFP_KERNEL);
-+ if (!dynamic_mc_io) {
-+ error = -ENOMEM;
-+ goto err_unlock;
-+ }
-+
-+ root_mc_dev = to_fsl_mc_device(restool_misc->dev);
-+ error = fsl_mc_portal_allocate(root_mc_dev, 0, &dynamic_mc_io);
-+ if (error < 0) {
-+ pr_err("Not able to allocate MC portal\n");
-+ goto free_dynamic_mc_io;
-+ }
-+ ++restool_misc->dynamic_instance_count;
-+ filep->private_data = dynamic_mc_io;
-+ }
-+
-+ mutex_unlock(&restool_misc->mutex);
-+
-+ return 0;
-+
-+free_dynamic_mc_io:
-+ kfree(dynamic_mc_io);
-+err_unlock:
-+ mutex_unlock(&restool_misc->mutex);
-+
-+ return error;
-+}
-+
-+static int fsl_mc_restool_dev_release(struct inode *inode, struct file *filep)
-+{
-+ struct fsl_mc_io *local_mc_io = filep->private_data;
-+ struct restool_misc *restool_misc = NULL;
-+ struct restool_misc *restool_misc_cursor;
-+
-+ if (WARN_ON(!filep->private_data))
-+ return -EINVAL;
-+
-+ mutex_lock(&misc_list_mutex);
-+
-+ list_for_each_entry(restool_misc_cursor, &misc_list, list) {
-+ if (restool_misc_cursor->miscdevt == inode->i_rdev) {
-+ restool_misc = restool_misc_cursor;
-+ break;
-+ }
-+ }
-+
-+ mutex_unlock(&misc_list_mutex);
-+
-+ if (!restool_misc)
-+ return -EINVAL;
-+
-+ mutex_lock(&restool_misc->mutex);
-+
-+ if (WARN_ON(restool_misc->dynamic_instance_count == 0 &&
-+ !restool_misc->static_instance_in_use)) {
-+ mutex_unlock(&restool_misc->mutex);
-+ return -EINVAL;
-+ }
-+
-+ /* Globally clean up opened/untracked handles */
-+ fsl_mc_portal_reset(local_mc_io);
-+
-+ /*
-+ * must check
-+ * whether local_mc_io is dynamic or static instance
-+ * Otherwise it will free up the reserved portal by accident
-+ * or even not free up the dynamic allocated portal
-+ * if 2 or more instances running concurrently
-+ */
-+ if (local_mc_io == restool_misc->static_mc_io) {
-+ restool_misc->static_instance_in_use = false;
-+ } else {
-+ fsl_mc_portal_free(local_mc_io);
-+ kfree(filep->private_data);
-+ --restool_misc->dynamic_instance_count;
-+ }
-+
-+ filep->private_data = NULL;
-+ mutex_unlock(&restool_misc->mutex);
-+
-+ return 0;
-+}
-+
-+static int restool_send_mc_command(unsigned long arg,
-+ struct fsl_mc_io *local_mc_io)
-+{
-+ int error;
-+ struct mc_command mc_cmd;
-+
-+ if (copy_from_user(&mc_cmd, (void __user *)arg, sizeof(mc_cmd)))
-+ return -EFAULT;
-+
-+ /*
-+ * Send MC command to the MC:
-+ */
-+ error = mc_send_command(local_mc_io, &mc_cmd);
-+ if (error < 0)
-+ return error;
-+
-+ if (copy_to_user((void __user *)arg, &mc_cmd, sizeof(mc_cmd)))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+
-+static long
-+fsl_mc_restool_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-+{
-+ int error;
-+
-+ switch (cmd) {
-+ case RESTOOL_SEND_MC_COMMAND:
-+ error = restool_send_mc_command(arg, file->private_data);
-+ break;
-+ default:
-+ pr_err("%s: unexpected ioctl call number\n", __func__);
-+ error = -EINVAL;
-+ }
-+
-+ return error;
-+}
-+
-+static const struct file_operations fsl_mc_restool_dev_fops = {
-+ .owner = THIS_MODULE,
-+ .open = fsl_mc_restool_dev_open,
-+ .release = fsl_mc_restool_dev_release,
-+ .unlocked_ioctl = fsl_mc_restool_dev_ioctl,
-+};
-+
-+static int restool_add_device_file(struct device *dev)
-+{
-+ u32 name1 = 0;
-+ char name2[20] = {0};
-+ int error;
-+ struct fsl_mc_device *root_mc_dev;
-+ struct restool_misc *restool_misc;
-+
-+ if (dev->bus == &platform_bus_type && dev->driver_data) {
-+ if (sscanf(dev_name(dev), "%x.%s", &name1, name2) != 2)
-+ return -EINVAL;
-+
-+ if (strcmp(name2, "fsl-mc") == 0)
-+ pr_debug("platform's root dprc name is: %s\n",
-+ dev_name(&(((struct fsl_mc *)
-+ (dev->driver_data))->root_mc_bus_dev->dev)));
-+ }
-+
-+ if (!fsl_mc_is_root_dprc(dev))
-+ return 0;
-+
-+ restool_misc = kzalloc(sizeof(*restool_misc), GFP_KERNEL);
-+ if (!restool_misc)
-+ return -ENOMEM;
-+
-+ restool_misc->dev = dev;
-+ root_mc_dev = to_fsl_mc_device(dev);
-+ error = fsl_mc_portal_allocate(root_mc_dev, 0,
-+ &restool_misc->static_mc_io);
-+ if (error < 0) {
-+ pr_err("Not able to allocate MC portal\n");
-+ goto free_restool_misc;
-+ }
-+
-+ restool_misc->misc.minor = MISC_DYNAMIC_MINOR;
-+ restool_misc->misc.name = dev_name(dev);
-+ restool_misc->misc.fops = &fsl_mc_restool_dev_fops;
-+
-+ error = misc_register(&restool_misc->misc);
-+ if (error < 0) {
-+ pr_err("misc_register() failed: %d\n", error);
-+ goto free_portal;
-+ }
-+
-+ restool_misc->miscdevt = restool_misc->misc.this_device->devt;
-+ mutex_init(&restool_misc->mutex);
-+ mutex_lock(&misc_list_mutex);
-+ list_add(&restool_misc->list, &misc_list);
-+ mutex_unlock(&misc_list_mutex);
-+
-+ pr_info("/dev/%s driver registered\n", dev_name(dev));
-+
-+ return 0;
-+
-+free_portal:
-+ fsl_mc_portal_free(restool_misc->static_mc_io);
-+free_restool_misc:
-+ kfree(restool_misc);
-+
-+ return error;
-+}
-+
-+static int restool_bus_notifier(struct notifier_block *nb,
-+ unsigned long action, void *data)
-+{
-+ int error;
-+ struct device *dev = data;
-+
-+ switch (action) {
-+ case BUS_NOTIFY_ADD_DEVICE:
-+ error = restool_add_device_file(dev);
-+ if (error)
-+ return error;
-+ break;
-+ case BUS_NOTIFY_DEL_DEVICE:
-+ case BUS_NOTIFY_REMOVED_DEVICE:
-+ case BUS_NOTIFY_BIND_DRIVER:
-+ case BUS_NOTIFY_BOUND_DRIVER:
-+ case BUS_NOTIFY_UNBIND_DRIVER:
-+ case BUS_NOTIFY_UNBOUND_DRIVER:
-+ break;
-+ default:
-+ pr_err("%s: unrecognized device action from %s\n", __func__,
-+ dev_name(dev));
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int add_to_restool(struct device *dev, void *data)
-+{
-+ return restool_add_device_file(dev);
-+}
-+
-+static int __init fsl_mc_restool_driver_init(void)
-+{
-+ int error;
-+ struct notifier_block *nb;
-+
-+ nb = kzalloc(sizeof(*nb), GFP_KERNEL);
-+ if (!nb)
-+ return -ENOMEM;
-+
-+ nb->notifier_call = restool_bus_notifier;
-+ error = bus_register_notifier(&fsl_mc_bus_type, nb);
-+ if (error)
-+ goto free_nb;
-+
-+ /*
-+ * This driver runs after fsl-mc bus driver runs.
-+ * Hence, many of the root dprcs are already attached to fsl-mc bus
-+ * In order to make sure we find all the root dprcs,
-+ * we need to scan the fsl_mc_bus_type.
-+ */
-+ error = bus_for_each_dev(&fsl_mc_bus_type, NULL, NULL, add_to_restool);
-+ if (error) {
-+ bus_unregister_notifier(&fsl_mc_bus_type, nb);
-+ kfree(nb);
-+ pr_err("restool driver registration failure\n");
-+ return error;
-+ }
-+
-+ return 0;
-+
-+free_nb:
-+ kfree(nb);
-+ return error;
-+}
-+
-+module_init(fsl_mc_restool_driver_init);
-+
-+static void __exit fsl_mc_restool_driver_exit(void)
-+{
-+ struct restool_misc *restool_misc;
-+ struct restool_misc *restool_misc_tmp;
-+ char name1[20] = {0};
-+ u32 name2 = 0;
-+
-+ list_for_each_entry_safe(restool_misc, restool_misc_tmp,
-+ &misc_list, list) {
-+ if (sscanf(restool_misc->misc.name, "%4s.%u", name1, &name2)
-+ != 2)
-+ continue;
-+
-+ pr_debug("name1=%s,name2=%u\n", name1, name2);
-+ pr_debug("misc-device: %s\n", restool_misc->misc.name);
-+ if (strcmp(name1, "dprc") != 0)
-+ continue;
-+
-+ if (WARN_ON(!restool_misc->static_mc_io))
-+ return;
-+
-+ if (WARN_ON(restool_misc->dynamic_instance_count != 0))
-+ return;
-+
-+ if (WARN_ON(restool_misc->static_instance_in_use))
-+ return;
-+
-+ misc_deregister(&restool_misc->misc);
-+ pr_info("/dev/%s driver unregistered\n",
-+ restool_misc->misc.name);
-+ fsl_mc_portal_free(restool_misc->static_mc_io);
-+ list_del(&restool_misc->list);
-+ kfree(restool_misc);
-+ }
-+}
-+
-+module_exit(fsl_mc_restool_driver_exit);
-+
-+MODULE_AUTHOR("Freescale Semiconductor Inc.");
-+MODULE_DESCRIPTION("Freescale's MC restool driver");
-+MODULE_LICENSE("GPL");