misc: mic: MIC COSM bus
authorAshutosh Dixit <ashutosh.dixit@intel.com>
Wed, 30 Sep 2015 01:12:03 +0000 (18:12 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 4 Oct 2015 11:46:06 +0000 (12:46 +0100)
The MIC COSM bus allows the co-processor state management (COSM)
functionality to be shared between multiple generations of Intel MIC
products. The COSM driver registers itself on the COSM bus. The base
PCIe drivers implement the bus ops and register COSM devices on the
bus, resulting in the COSM driver being probed with the COSM devices.
COSM bus ops, e.g. start, stop, ready, reset, therefore abstract out
common functionality from its specific implementation for individual
generations of MIC products.

Reviewed-by: Nikhil Rao <nikhil.rao@intel.com>
Reviewed-by: Sudeep Dutt <sudeep.dutt@intel.com>
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/misc/mic/Kconfig
drivers/misc/mic/bus/Makefile
drivers/misc/mic/bus/cosm_bus.c [new file with mode: 0644]
drivers/misc/mic/bus/cosm_bus.h [new file with mode: 0644]

index e9f2f56c370de4fb3c61fb638bd9ccc7dd54efc3..1488232317c5007b61686beaffca568d6e0b4b9f 100644 (file)
@@ -36,7 +36,7 @@ comment "Intel MIC Host Driver"
 
 config INTEL_MIC_HOST
        tristate "Intel MIC Host Driver"
-       depends on 64BIT && PCI && X86 && INTEL_MIC_BUS && SCIF_BUS
+       depends on 64BIT && PCI && X86 && INTEL_MIC_BUS && SCIF_BUS && MIC_COSM
        select VHOST_RING
        help
          This enables Host Driver support for the Intel Many Integrated
@@ -56,7 +56,7 @@ comment "Intel MIC Card Driver"
 
 config INTEL_MIC_CARD
        tristate "Intel MIC Card Driver"
-       depends on 64BIT && X86 && INTEL_MIC_BUS && SCIF_BUS
+       depends on 64BIT && X86 && INTEL_MIC_BUS && SCIF_BUS && MIC_COSM
        select VIRTIO
        help
          This enables card driver support for the Intel Many Integrated
@@ -88,3 +88,21 @@ config SCIF
          More information about the Intel MIC family as well as the Linux
          OS and tools for MIC to use with this driver are available from
          <http://software.intel.com/en-us/mic-developer>.
+
+comment "Intel MIC Coprocessor State Management (COSM) Drivers"
+
+config MIC_COSM
+       tristate "Intel MIC Coprocessor State Management (COSM) Drivers"
+       depends on 64BIT && PCI && X86 && SCIF
+       help
+         This enables COSM driver support for the Intel Many
+         Integrated Core (MIC) family of PCIe form factor coprocessor
+         devices. COSM drivers implement functions such as boot,
+         shutdown, reset and reboot of MIC devices.
+
+         If you are building a host kernel with an Intel MIC device then
+         say M (recommended) or Y, else say N. If unsure say N.
+
+         More information about the Intel MIC family as well as the Linux
+         OS and tools for MIC to use with this driver are available from
+         <http://software.intel.com/en-us/mic-developer>.
index 1ed37e234c969916eeef671cb6dabefae30e4e94..761842b0d0bb2eb7bc34c5361e4e5b60e5f5613a 100644 (file)
@@ -4,3 +4,4 @@
 #
 obj-$(CONFIG_INTEL_MIC_BUS) += mic_bus.o
 obj-$(CONFIG_SCIF_BUS) += scif_bus.o
+obj-$(CONFIG_MIC_COSM) += cosm_bus.o
diff --git a/drivers/misc/mic/bus/cosm_bus.c b/drivers/misc/mic/bus/cosm_bus.c
new file mode 100644 (file)
index 0000000..1e36830
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2015 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC COSM Bus Driver
+ */
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/idr.h>
+#include "cosm_bus.h"
+
+/* Unique numbering for cosm devices. */
+static DEFINE_IDA(cosm_index_ida);
+
+static int cosm_dev_probe(struct device *d)
+{
+       struct cosm_device *dev = dev_to_cosm(d);
+       struct cosm_driver *drv = drv_to_cosm(dev->dev.driver);
+
+       return drv->probe(dev);
+}
+
+static int cosm_dev_remove(struct device *d)
+{
+       struct cosm_device *dev = dev_to_cosm(d);
+       struct cosm_driver *drv = drv_to_cosm(dev->dev.driver);
+
+       drv->remove(dev);
+       return 0;
+}
+
+static struct bus_type cosm_bus = {
+       .name  = "cosm_bus",
+       .probe = cosm_dev_probe,
+       .remove = cosm_dev_remove,
+};
+
+int cosm_register_driver(struct cosm_driver *driver)
+{
+       driver->driver.bus = &cosm_bus;
+       return driver_register(&driver->driver);
+}
+EXPORT_SYMBOL_GPL(cosm_register_driver);
+
+void cosm_unregister_driver(struct cosm_driver *driver)
+{
+       driver_unregister(&driver->driver);
+}
+EXPORT_SYMBOL_GPL(cosm_unregister_driver);
+
+static inline void cosm_release_dev(struct device *d)
+{
+       struct cosm_device *cdev = dev_to_cosm(d);
+
+       kfree(cdev);
+}
+
+struct cosm_device *
+cosm_register_device(struct device *pdev, struct cosm_hw_ops *hw_ops)
+{
+       struct cosm_device *cdev;
+       int ret;
+
+       cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
+       if (!cdev)
+               return ERR_PTR(-ENOMEM);
+
+       cdev->dev.parent = pdev;
+       cdev->dev.release = cosm_release_dev;
+       cdev->hw_ops = hw_ops;
+       dev_set_drvdata(&cdev->dev, cdev);
+       cdev->dev.bus = &cosm_bus;
+
+       /* Assign a unique device index and hence name */
+       ret = ida_simple_get(&cosm_index_ida, 0, 0, GFP_KERNEL);
+       if (ret < 0)
+               goto free_cdev;
+
+       cdev->index = ret;
+       cdev->dev.id = ret;
+       dev_set_name(&cdev->dev, "cosm-dev%u", cdev->index);
+
+       ret = device_register(&cdev->dev);
+       if (ret)
+               goto ida_remove;
+       return cdev;
+ida_remove:
+       ida_simple_remove(&cosm_index_ida, cdev->index);
+free_cdev:
+       kfree(cdev);
+       return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(cosm_register_device);
+
+void cosm_unregister_device(struct cosm_device *dev)
+{
+       int index = dev->index; /* save for after device release */
+
+       device_unregister(&dev->dev);
+       ida_simple_remove(&cosm_index_ida, index);
+}
+EXPORT_SYMBOL_GPL(cosm_unregister_device);
+
+struct cosm_device *cosm_find_cdev_by_id(int id)
+{
+       struct device *dev = subsys_find_device_by_id(&cosm_bus, id, NULL);
+
+       return dev ? container_of(dev, struct cosm_device, dev) : NULL;
+}
+EXPORT_SYMBOL_GPL(cosm_find_cdev_by_id);
+
+static int __init cosm_init(void)
+{
+       return bus_register(&cosm_bus);
+}
+
+static void __exit cosm_exit(void)
+{
+       bus_unregister(&cosm_bus);
+       ida_destroy(&cosm_index_ida);
+}
+
+core_initcall(cosm_init);
+module_exit(cosm_exit);
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_DESCRIPTION("Intel(R) MIC card OS state management bus driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/mic/bus/cosm_bus.h b/drivers/misc/mic/bus/cosm_bus.h
new file mode 100644 (file)
index 0000000..f7c57f2
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2015 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC COSM Bus Driver
+ */
+#ifndef _COSM_BUS_H_
+#define _COSM_BUS_H_
+
+#include <linux/scif.h>
+#include <linux/mic_common.h>
+#include "../common/mic_dev.h"
+
+/**
+ * cosm_device - representation of a cosm device
+ *
+ * @attr_group: Pointer to list of sysfs attribute groups.
+ * @sdev: Device for sysfs entries.
+ * @state: MIC state.
+ * @shutdown_status: MIC status reported by card for shutdown/crashes.
+ * @shutdown_status_int: Internal shutdown status maintained by the driver
+ * @cosm_mutex: Mutex for synchronizing access to data structures.
+ * @reset_trigger_work: Work for triggering reset requests.
+ * @scif_work: Work for handling per device SCIF connections
+ * @cmdline: Kernel command line.
+ * @firmware: Firmware file name.
+ * @ramdisk: Ramdisk file name.
+ * @bootmode: Boot mode i.e. "linux" or "elf" for flash updates.
+ * @log_buf_addr: Log buffer address for MIC.
+ * @log_buf_len: Log buffer length address for MIC.
+ * @state_sysfs: Sysfs dirent for notifying ring 3 about MIC state changes.
+ * @hw_ops: the hardware bus ops for this device.
+ * @dev: underlying device.
+ * @index: unique position on the cosm bus
+ * @dbg_dir: debug fs directory
+ * @newepd: new endpoint from scif accept to be assigned to this cdev
+ * @epd: SCIF endpoint for this cdev
+ * @heartbeat_watchdog_enable: if heartbeat watchdog is enabled for this cdev
+ * @sysfs_heartbeat_enable: sysfs setting for disabling heartbeat notification
+ */
+struct cosm_device {
+       const struct attribute_group **attr_group;
+       struct device *sdev;
+       u8 state;
+       u8 shutdown_status;
+       u8 shutdown_status_int;
+       struct mutex cosm_mutex;
+       struct work_struct reset_trigger_work;
+       struct work_struct scif_work;
+       char *cmdline;
+       char *firmware;
+       char *ramdisk;
+       char *bootmode;
+       void *log_buf_addr;
+       int *log_buf_len;
+       struct kernfs_node *state_sysfs;
+       struct cosm_hw_ops *hw_ops;
+       struct device dev;
+       int index;
+       struct dentry *dbg_dir;
+       scif_epd_t newepd;
+       scif_epd_t epd;
+       bool heartbeat_watchdog_enable;
+       bool sysfs_heartbeat_enable;
+};
+
+/**
+ * cosm_driver - operations for a cosm driver
+ *
+ * @driver: underlying device driver (populate name and owner).
+ * @probe: the function to call when a device is found.  Returns 0 or -errno.
+ * @remove: the function to call when a device is removed.
+ */
+struct cosm_driver {
+       struct device_driver driver;
+       int (*probe)(struct cosm_device *dev);
+       void (*remove)(struct cosm_device *dev);
+};
+
+/**
+ * cosm_hw_ops - cosm bus ops
+ *
+ * @reset: trigger MIC reset
+ * @force_reset: force MIC reset
+ * @post_reset: inform MIC reset is complete
+ * @ready: is MIC ready for OS download
+ * @start: boot MIC
+ * @stop: prepare MIC for reset
+ * @family: return MIC HW family string
+ * @stepping: return MIC HW stepping string
+ * @aper: return MIC PCIe aperture
+ */
+struct cosm_hw_ops {
+       void (*reset)(struct cosm_device *cdev);
+       void (*force_reset)(struct cosm_device *cdev);
+       void (*post_reset)(struct cosm_device *cdev, enum mic_states state);
+       bool (*ready)(struct cosm_device *cdev);
+       int (*start)(struct cosm_device *cdev, int id);
+       void (*stop)(struct cosm_device *cdev, bool force);
+       ssize_t (*family)(struct cosm_device *cdev, char *buf);
+       ssize_t (*stepping)(struct cosm_device *cdev, char *buf);
+       struct mic_mw *(*aper)(struct cosm_device *cdev);
+};
+
+struct cosm_device *
+cosm_register_device(struct device *pdev, struct cosm_hw_ops *hw_ops);
+void cosm_unregister_device(struct cosm_device *dev);
+int cosm_register_driver(struct cosm_driver *drv);
+void cosm_unregister_driver(struct cosm_driver *drv);
+struct cosm_device *cosm_find_cdev_by_id(int id);
+
+static inline struct cosm_device *dev_to_cosm(struct device *dev)
+{
+       return container_of(dev, struct cosm_device, dev);
+}
+
+static inline struct cosm_driver *drv_to_cosm(struct device_driver *drv)
+{
+       return container_of(drv, struct cosm_driver, driver);
+}
+#endif /* _COSM_BUS_H */