/*
 * 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 const struct pci_device_id 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->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.
 *
 * @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_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;
	}
	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");
