These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / misc / mic / host / mic_main.c
index ab37a31..153894e 100644 (file)
  * the file called "COPYING".
  *
  * Intel MIC Host driver.
- *
- * Global TODO's across the driver to be added after initial base
- * patches are accepted upstream:
- * 1) Enable DMA support.
- * 2) Enable per vring interrupt support.
  */
 #include <linux/fs.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/poll.h>
-#include <linux/suspend.h>
 
 #include <linux/mic_common.h>
 #include "../common/mic_dev.h"
@@ -63,8 +57,6 @@ MODULE_DEVICE_TABLE(pci, mic_pci_tbl);
 
 /* ID allocator for MIC devices */
 static struct ida g_mic_ida;
-/* Class of MIC devices for sysfs accessibility. */
-static struct class *g_mic_class;
 /* Base device node number for MIC devices */
 static dev_t g_mic_devno;
 
@@ -81,17 +73,14 @@ static const struct file_operations mic_fops = {
 static int mic_dp_init(struct mic_device *mdev)
 {
        mdev->dp = kzalloc(MIC_DP_SIZE, GFP_KERNEL);
-       if (!mdev->dp) {
-               dev_err(mdev->sdev->parent, "%s %d err %d\n",
-                       __func__, __LINE__, -ENOMEM);
+       if (!mdev->dp)
                return -ENOMEM;
-       }
 
        mdev->dp_dma_addr = mic_map_single(mdev,
                mdev->dp, MIC_DP_SIZE);
        if (mic_map_error(mdev->dp_dma_addr)) {
                kfree(mdev->dp);
-               dev_err(mdev->sdev->parent, "%s %d err %d\n",
+               dev_err(&mdev->pdev->dev, "%s %d err %d\n",
                        __func__, __LINE__, -ENOMEM);
                return -ENOMEM;
        }
@@ -107,30 +96,6 @@ static void mic_dp_uninit(struct mic_device *mdev)
        kfree(mdev->dp);
 }
 
-/**
- * mic_shutdown_db - Shutdown doorbell interrupt handler.
- */
-static irqreturn_t mic_shutdown_db(int irq, void *data)
-{
-       struct mic_device *mdev = data;
-       struct mic_bootparam *bootparam = mdev->dp;
-
-       mdev->ops->intr_workarounds(mdev);
-
-       switch (bootparam->shutdown_status) {
-       case MIC_HALTED:
-       case MIC_POWER_OFF:
-       case MIC_RESTART:
-               /* Fall through */
-       case MIC_CRASHED:
-               schedule_work(&mdev->shutdown_work);
-               break;
-       default:
-               break;
-       };
-       return IRQ_HANDLED;
-}
-
 /**
  * mic_ops_init: Initialize HW specific operation tables.
  *
@@ -187,43 +152,6 @@ static enum mic_hw_family mic_get_family(struct pci_dev *pdev)
        return family;
 }
 
-/**
-* mic_pm_notifier: Notifier callback function that handles
-* PM notifications.
-*
-* @notifier_block: The notifier structure.
-* @pm_event: The event for which the driver was notified.
-* @unused: Meaningless. Always NULL.
-*
-* returns NOTIFY_DONE
-*/
-static int mic_pm_notifier(struct notifier_block *notifier,
-               unsigned long pm_event, void *unused)
-{
-       struct mic_device *mdev = container_of(notifier,
-               struct mic_device, pm_notifier);
-
-       switch (pm_event) {
-       case PM_HIBERNATION_PREPARE:
-               /* Fall through */
-       case PM_SUSPEND_PREPARE:
-               mic_prepare_suspend(mdev);
-               break;
-       case PM_POST_HIBERNATION:
-               /* Fall through */
-       case PM_POST_SUSPEND:
-               /* Fall through */
-       case PM_POST_RESTORE:
-               mic_complete_resume(mdev);
-               break;
-       case PM_RESTORE_PREPARE:
-               break;
-       default:
-               break;
-       }
-       return NOTIFY_DONE;
-}
-
 /**
  * mic_device_init - Allocates and initializes the MIC device structure
  *
@@ -232,52 +160,16 @@ static int mic_pm_notifier(struct notifier_block *notifier,
  *
  * returns none.
  */
-static int
+static void
 mic_device_init(struct mic_device *mdev, struct pci_dev *pdev)
 {
-       int rc;
-
+       mdev->pdev = pdev;
        mdev->family = mic_get_family(pdev);
        mdev->stepping = pdev->revision;
        mic_ops_init(mdev);
-       mic_sysfs_init(mdev);
        mutex_init(&mdev->mic_mutex);
        mdev->irq_info.next_avail_src = 0;
-       INIT_WORK(&mdev->reset_trigger_work, mic_reset_trigger_work);
-       INIT_WORK(&mdev->shutdown_work, mic_shutdown_work);
-       init_completion(&mdev->reset_wait);
        INIT_LIST_HEAD(&mdev->vdev_list);
-       mdev->pm_notifier.notifier_call = mic_pm_notifier;
-       rc = register_pm_notifier(&mdev->pm_notifier);
-       if (rc) {
-               dev_err(&pdev->dev, "register_pm_notifier failed rc %d\n",
-                       rc);
-               goto register_pm_notifier_fail;
-       }
-       return 0;
-register_pm_notifier_fail:
-       flush_work(&mdev->shutdown_work);
-       flush_work(&mdev->reset_trigger_work);
-       return rc;
-}
-
-/**
- * mic_device_uninit - Frees resources allocated during mic_device_init(..)
- *
- * @mdev: pointer to mic_device instance
- *
- * returns none
- */
-static void mic_device_uninit(struct mic_device *mdev)
-{
-       /* The cmdline sysfs entry might have allocated cmdline */
-       kfree(mdev->cmdline);
-       kfree(mdev->firmware);
-       kfree(mdev->ramdisk);
-       kfree(mdev->bootmode);
-       flush_work(&mdev->reset_trigger_work);
-       flush_work(&mdev->shutdown_work);
-       unregister_pm_notifier(&mdev->pm_notifier);
 }
 
 /**
@@ -289,7 +181,7 @@ static void mic_device_uninit(struct mic_device *mdev)
  * returns 0 on success, < 0 on failure.
  */
 static int mic_probe(struct pci_dev *pdev,
-               const struct pci_device_id *ent)
+                    const struct pci_device_id *ent)
 {
        int rc;
        struct mic_device *mdev;
@@ -307,16 +199,12 @@ static int mic_probe(struct pci_dev *pdev,
                goto ida_fail;
        }
 
-       rc = mic_device_init(mdev, pdev);
-       if (rc) {
-               dev_err(&pdev->dev, "mic_device_init failed rc %d\n", rc);
-               goto device_init_fail;
-       }
+       mic_device_init(mdev, pdev);
 
        rc = pci_enable_device(pdev);
        if (rc) {
                dev_err(&pdev->dev, "failed to enable pci device.\n");
-               goto uninit_device;
+               goto ida_remove;
        }
 
        pci_set_master(pdev);
@@ -365,61 +253,39 @@ static int mic_probe(struct pci_dev *pdev,
 
        pci_set_drvdata(pdev, mdev);
 
-       mdev->sdev = device_create_with_groups(g_mic_class, &pdev->dev,
-               MKDEV(MAJOR(g_mic_devno), mdev->id), NULL,
-               mdev->attr_group, "mic%d", mdev->id);
-       if (IS_ERR(mdev->sdev)) {
-               rc = PTR_ERR(mdev->sdev);
-               dev_err(&pdev->dev,
-                       "device_create_with_groups failed rc %d\n", rc);
-               goto smpt_uninit;
-       }
-       mdev->state_sysfs = sysfs_get_dirent(mdev->sdev->kobj.sd, "state");
-       if (!mdev->state_sysfs) {
-               rc = -ENODEV;
-               dev_err(&pdev->dev, "sysfs_get_dirent failed rc %d\n", rc);
-               goto destroy_device;
-       }
-
        rc = mic_dp_init(mdev);
        if (rc) {
                dev_err(&pdev->dev, "mic_dp_init failed rc %d\n", rc);
-               goto sysfs_put;
-       }
-       mutex_lock(&mdev->mic_mutex);
-
-       mdev->shutdown_db = mic_next_db(mdev);
-       mdev->shutdown_cookie = mic_request_threaded_irq(mdev, mic_shutdown_db,
-                                       NULL, "shutdown-interrupt", mdev,
-                                       mdev->shutdown_db, MIC_INTR_DB);
-       if (IS_ERR(mdev->shutdown_cookie)) {
-               rc = PTR_ERR(mdev->shutdown_cookie);
-               mutex_unlock(&mdev->mic_mutex);
-               goto dp_uninit;
+               goto smpt_uninit;
        }
-       mutex_unlock(&mdev->mic_mutex);
        mic_bootparam_init(mdev);
 
        mic_create_debug_dir(mdev);
-       cdev_init(&mdev->cdev, &mic_fops);
-       mdev->cdev.owner = THIS_MODULE;
-       rc = cdev_add(&mdev->cdev, MKDEV(MAJOR(g_mic_devno), mdev->id), 1);
+
+       mdev->miscdev.minor = MISC_DYNAMIC_MINOR;
+       snprintf(mdev->name, sizeof(mdev->name), "mic%d", mdev->id);
+       mdev->miscdev.name = mdev->name;
+       mdev->miscdev.fops = &mic_fops;
+       mdev->miscdev.parent = &mdev->pdev->dev;
+       rc = misc_register(&mdev->miscdev);
        if (rc) {
-               dev_err(&pdev->dev, "cdev_add err id %d rc %d\n", mdev->id, rc);
+               dev_err(&pdev->dev, "misc_register err id %d rc %d\n",
+                       mdev->id, rc);
                goto cleanup_debug_dir;
        }
+
+       mdev->cosm_dev = cosm_register_device(&mdev->pdev->dev, &cosm_hw_ops);
+       if (IS_ERR(mdev->cosm_dev)) {
+               rc = PTR_ERR(mdev->cosm_dev);
+               dev_err(&pdev->dev, "cosm_add_device failed rc %d\n", rc);
+               goto misc_dereg;
+       }
        return 0;
+misc_dereg:
+       misc_deregister(&mdev->miscdev);
 cleanup_debug_dir:
        mic_delete_debug_dir(mdev);
-       mutex_lock(&mdev->mic_mutex);
-       mic_free_irq(mdev, mdev->shutdown_cookie, mdev);
-       mutex_unlock(&mdev->mic_mutex);
-dp_uninit:
        mic_dp_uninit(mdev);
-sysfs_put:
-       sysfs_put(mdev->state_sysfs);
-destroy_device:
-       device_destroy(g_mic_class, MKDEV(MAJOR(g_mic_devno), mdev->id));
 smpt_uninit:
        mic_smpt_uninit(mdev);
 free_interrupts:
@@ -432,9 +298,7 @@ release_regions:
        pci_release_regions(pdev);
 disable_device:
        pci_disable_device(pdev);
-uninit_device:
-       mic_device_uninit(mdev);
-device_init_fail:
+ida_remove:
        ida_simple_remove(&g_mic_ida, mdev->id);
 ida_fail:
        kfree(mdev);
@@ -458,26 +322,20 @@ static void mic_remove(struct pci_dev *pdev)
        if (!mdev)
                return;
 
-       mic_stop(mdev, false);
-       cdev_del(&mdev->cdev);
+       cosm_unregister_device(mdev->cosm_dev);
+       misc_deregister(&mdev->miscdev);
        mic_delete_debug_dir(mdev);
-       mutex_lock(&mdev->mic_mutex);
-       mic_free_irq(mdev, mdev->shutdown_cookie, mdev);
-       mutex_unlock(&mdev->mic_mutex);
-       flush_work(&mdev->shutdown_work);
        mic_dp_uninit(mdev);
-       sysfs_put(mdev->state_sysfs);
-       device_destroy(g_mic_class, MKDEV(MAJOR(g_mic_devno), mdev->id));
        mic_smpt_uninit(mdev);
        mic_free_interrupts(mdev, pdev);
-       iounmap(mdev->mmio.va);
        iounmap(mdev->aper.va);
-       mic_device_uninit(mdev);
+       iounmap(mdev->mmio.va);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
        ida_simple_remove(&g_mic_ida, mdev->id);
        kfree(mdev);
 }
+
 static struct pci_driver mic_driver = {
        .name = mic_driver_name,
        .id_table = mic_pci_tbl,
@@ -490,31 +348,23 @@ static int __init mic_init(void)
        int ret;
 
        ret = alloc_chrdev_region(&g_mic_devno, 0,
-               MIC_MAX_NUM_DEVS, mic_driver_name);
+                                 MIC_MAX_NUM_DEVS, mic_driver_name);
        if (ret) {
                pr_err("alloc_chrdev_region failed ret %d\n", ret);
                goto error;
        }
 
-       g_mic_class = class_create(THIS_MODULE, mic_driver_name);
-       if (IS_ERR(g_mic_class)) {
-               ret = PTR_ERR(g_mic_class);
-               pr_err("class_create failed ret %d\n", ret);
-               goto cleanup_chrdev;
-       }
-
        mic_init_debugfs();
        ida_init(&g_mic_ida);
        ret = pci_register_driver(&mic_driver);
        if (ret) {
                pr_err("pci_register_driver failed ret %d\n", ret);
-               goto cleanup_debugfs;
+               goto cleanup_chrdev;
        }
        return ret;
-cleanup_debugfs:
-       mic_exit_debugfs();
-       class_destroy(g_mic_class);
 cleanup_chrdev:
+       ida_destroy(&g_mic_ida);
+       mic_exit_debugfs();
        unregister_chrdev_region(g_mic_devno, MIC_MAX_NUM_DEVS);
 error:
        return ret;
@@ -525,7 +375,6 @@ static void __exit mic_exit(void)
        pci_unregister_driver(&mic_driver);
        ida_destroy(&g_mic_ida);
        mic_exit_debugfs();
-       class_destroy(g_mic_class);
        unregister_chrdev_region(g_mic_devno, MIC_MAX_NUM_DEVS);
 }