diff options
Diffstat (limited to 'drivers/misc/mic/host/mic_main.c')
-rw-r--r-- | drivers/misc/mic/host/mic_main.c | 536 |
1 files changed, 0 insertions, 536 deletions
diff --git a/drivers/misc/mic/host/mic_main.c b/drivers/misc/mic/host/mic_main.c deleted file mode 100644 index ad838c7..0000000 --- a/drivers/misc/mic/host/mic_main.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2013 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 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" -#include "mic_device.h" -#include "mic_x100.h" -#include "mic_smpt.h" -#include "mic_fops.h" -#include "mic_virtio.h" - -static const char mic_driver_name[] = "mic"; - -static DEFINE_PCI_DEVICE_TABLE(mic_pci_tbl) = { - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2250)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2251)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2252)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2253)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2254)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2255)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2256)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2257)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2258)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2259)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225a)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225b)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225c)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225d)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225e)}, - - /* required last entry */ - { 0, } -}; - -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; - -static const struct file_operations mic_fops = { - .open = mic_open, - .release = mic_release, - .unlocked_ioctl = mic_ioctl, - .poll = mic_poll, - .mmap = mic_mmap, - .owner = THIS_MODULE, -}; - -/* Initialize the device page */ -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); - 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", - __func__, __LINE__, -ENOMEM); - return -ENOMEM; - } - mdev->ops->write_spad(mdev, MIC_DPLO_SPAD, mdev->dp_dma_addr); - mdev->ops->write_spad(mdev, MIC_DPHI_SPAD, mdev->dp_dma_addr >> 32); - return 0; -} - -/* Uninitialize the device page */ -static void mic_dp_uninit(struct mic_device *mdev) -{ - mic_unmap_single(mdev, mdev->dp_dma_addr, MIC_DP_SIZE); - 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->ack_interrupt(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. - * - * @mdev: pointer to mic_device instance - * - * returns none. - */ -static void mic_ops_init(struct mic_device *mdev) -{ - switch (mdev->family) { - case MIC_FAMILY_X100: - mdev->ops = &mic_x100_ops; - mdev->intr_ops = &mic_x100_intr_ops; - mdev->smpt_ops = &mic_x100_smpt_ops; - break; - default: - break; - } -} - -/** - * mic_get_family - Determine hardware family to which this MIC belongs. - * - * @pdev: The pci device structure - * - * returns family. - */ -static enum mic_hw_family mic_get_family(struct pci_dev *pdev) -{ - enum mic_hw_family family; - - switch (pdev->device) { - case MIC_X100_PCI_DEVICE_2250: - case MIC_X100_PCI_DEVICE_2251: - case MIC_X100_PCI_DEVICE_2252: - case MIC_X100_PCI_DEVICE_2253: - case MIC_X100_PCI_DEVICE_2254: - case MIC_X100_PCI_DEVICE_2255: - case MIC_X100_PCI_DEVICE_2256: - case MIC_X100_PCI_DEVICE_2257: - case MIC_X100_PCI_DEVICE_2258: - case MIC_X100_PCI_DEVICE_2259: - case MIC_X100_PCI_DEVICE_225a: - case MIC_X100_PCI_DEVICE_225b: - case MIC_X100_PCI_DEVICE_225c: - case MIC_X100_PCI_DEVICE_225d: - case MIC_X100_PCI_DEVICE_225e: - family = MIC_FAMILY_X100; - break; - default: - family = MIC_FAMILY_UNKNOWN; - break; - } - 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 - * - * @mdev: pointer to mic_device instance - * @pdev: The pci device structure - * - * returns none. - */ -static int -mic_device_init(struct mic_device *mdev, struct pci_dev *pdev) -{ - int rc; - - 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); -} - -/** - * mic_probe - Device Initialization Routine - * - * @pdev: PCI device structure - * @ent: entry in mic_pci_tbl - * - * returns 0 on success, < 0 on failure. - */ -static int mic_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - int rc; - struct mic_device *mdev; - - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); - if (!mdev) { - rc = -ENOMEM; - dev_err(&pdev->dev, "mdev kmalloc failed rc %d\n", rc); - goto mdev_alloc_fail; - } - mdev->id = ida_simple_get(&g_mic_ida, 0, MIC_MAX_NUM_DEVS, GFP_KERNEL); - if (mdev->id < 0) { - rc = mdev->id; - dev_err(&pdev->dev, "ida_simple_get failed rc %d\n", rc); - 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; - } - - rc = pci_enable_device(pdev); - if (rc) { - dev_err(&pdev->dev, "failed to enable pci device.\n"); - goto uninit_device; - } - - pci_set_master(pdev); - - rc = pci_request_regions(pdev, mic_driver_name); - if (rc) { - dev_err(&pdev->dev, "failed to get pci regions.\n"); - goto disable_device; - } - - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); - if (rc) { - dev_err(&pdev->dev, "Cannot set DMA mask\n"); - goto release_regions; - } - - mdev->mmio.pa = pci_resource_start(pdev, mdev->ops->mmio_bar); - mdev->mmio.len = pci_resource_len(pdev, mdev->ops->mmio_bar); - mdev->mmio.va = pci_ioremap_bar(pdev, mdev->ops->mmio_bar); - if (!mdev->mmio.va) { - dev_err(&pdev->dev, "Cannot remap MMIO BAR\n"); - rc = -EIO; - goto release_regions; - } - - mdev->aper.pa = pci_resource_start(pdev, mdev->ops->aper_bar); - mdev->aper.len = pci_resource_len(pdev, mdev->ops->aper_bar); - mdev->aper.va = ioremap_wc(mdev->aper.pa, mdev->aper.len); - if (!mdev->aper.va) { - dev_err(&pdev->dev, "Cannot remap Aperture BAR\n"); - rc = -EIO; - goto unmap_mmio; - } - - mdev->intr_ops->intr_init(mdev); - rc = mic_setup_interrupts(mdev, pdev); - if (rc) { - dev_err(&pdev->dev, "mic_setup_interrupts failed %d\n", rc); - goto unmap_aper; - } - rc = mic_smpt_init(mdev); - if (rc) { - dev_err(&pdev->dev, "smpt_init failed %d\n", rc); - goto free_interrupts; - } - - 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_irq(mdev, mic_shutdown_db, - "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; - } - 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); - if (rc) { - dev_err(&pdev->dev, "cdev_add err id %d rc %d\n", mdev->id, rc); - goto cleanup_debug_dir; - } - return 0; -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: - mic_free_interrupts(mdev, pdev); -unmap_aper: - iounmap(mdev->aper.va); -unmap_mmio: - iounmap(mdev->mmio.va); -release_regions: - pci_release_regions(pdev); -disable_device: - pci_disable_device(pdev); -uninit_device: - mic_device_uninit(mdev); -device_init_fail: - ida_simple_remove(&g_mic_ida, mdev->id); -ida_fail: - kfree(mdev); -mdev_alloc_fail: - dev_err(&pdev->dev, "Probe failed rc %d\n", rc); - return rc; -} - -/** - * mic_remove - Device Removal Routine - * mic_remove is called by the PCI subsystem to alert the driver - * that it should release a PCI device. - * - * @pdev: PCI device structure - */ -static void mic_remove(struct pci_dev *pdev) -{ - struct mic_device *mdev; - - mdev = pci_get_drvdata(pdev); - if (!mdev) - return; - - mic_stop(mdev, false); - cdev_del(&mdev->cdev); - 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); - 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, - .probe = mic_probe, - .remove = mic_remove -}; - -static int __init mic_init(void) -{ - int ret; - - ret = alloc_chrdev_region(&g_mic_devno, 0, - 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; - } - return ret; -cleanup_debugfs: - mic_exit_debugfs(); - class_destroy(g_mic_class); -cleanup_chrdev: - unregister_chrdev_region(g_mic_devno, MIC_MAX_NUM_DEVS); -error: - return ret; -} - -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); -} - -module_init(mic_init); -module_exit(mic_exit); - -MODULE_AUTHOR("Intel Corporation"); -MODULE_DESCRIPTION("Intel(R) MIC X100 Host driver"); -MODULE_LICENSE("GPL v2"); |