Skip to content

Commit

Permalink
mei: sperate interface and pci code into two files
Browse files Browse the repository at this point in the history
leave misc file operations in the main
and move PCI related code into pci-me

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Tomas Winkler authored and Greg Kroah-Hartman committed Feb 6, 2013
1 parent 890537b commit 2703d4b
Show file tree
Hide file tree
Showing 4 changed files with 409 additions and 342 deletions.
1 change: 1 addition & 0 deletions drivers/misc/mei/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ mei-objs += main.o
mei-objs += amthif.o
mei-objs += wd.o
mei-objs += client.o
mei-objs += pci-me.o
354 changes: 12 additions & 342 deletions drivers/misc/mei/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,54 +43,6 @@
#include "hw-me.h"
#include "client.h"

/* AMT device is a singleton on the platform */
static struct pci_dev *mei_pdev;

/* mei_pci_tbl - PCI Device ID Table */
static DEFINE_PCI_DEVICE_TABLE(mei_pci_tbl) = {
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82946GZ)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G35)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82Q965)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G965)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GM965)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GME965)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q35)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82G33)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q33)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82X38)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_3200)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_6)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_7)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_8)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_9)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_10)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_1)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_2)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_3)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_4)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_1)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_2)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_3)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_4)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_1)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_2)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_CPT_1)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PBG_1)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_1)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_2)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_3)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_LP)},

/* required last entry */
{0, }
};

MODULE_DEVICE_TABLE(pci, mei_pci_tbl);

static DEFINE_MUTEX(mei_mutex);


/**
* mei_open - the open function
*
Expand All @@ -101,15 +53,20 @@ static DEFINE_MUTEX(mei_mutex);
*/
static int mei_open(struct inode *inode, struct file *file)
{
struct miscdevice *misc = file->private_data;
struct pci_dev *pdev;
struct mei_cl *cl;
struct mei_device *dev;

int err;

err = -ENODEV;
if (!mei_pdev)
if (!misc->parent)
goto out;

dev = pci_get_drvdata(mei_pdev);
pdev = container_of(misc->parent, struct pci_dev, dev);

dev = pci_get_drvdata(pdev);
if (!dev)
goto out;

Expand Down Expand Up @@ -787,7 +744,6 @@ static const struct file_operations mei_fops = {
.llseek = no_llseek
};


/*
* Misc Device Struct
*/
Expand All @@ -797,302 +753,16 @@ static struct miscdevice mei_misc_device = {
.minor = MISC_DYNAMIC_MINOR,
};

/**
* mei_quirk_probe - probe for devices that doesn't valid ME interface
* @pdev: PCI device structure
* @ent: entry into pci_device_table
*
* returns true if ME Interface is valid, false otherwise
*/
static bool mei_quirk_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
int mei_register(struct device *dev)
{
u32 reg;
if (ent->device == MEI_DEV_ID_PBG_1) {
pci_read_config_dword(pdev, 0x48, &reg);
/* make sure that bit 9 is up and bit 10 is down */
if ((reg & 0x600) == 0x200) {
dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n");
return false;
}
}
return true;
}
/**
* mei_probe - Device Initialization Routine
*
* @pdev: PCI device structure
* @ent: entry in kcs_pci_tbl
*
* returns 0 on success, <0 on failure.
*/
static int mei_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct mei_device *dev;
int err;

mutex_lock(&mei_mutex);

if (!mei_quirk_probe(pdev, ent)) {
err = -ENODEV;
goto end;
}

if (mei_pdev) {
err = -EEXIST;
goto end;
}
/* enable pci dev */
err = pci_enable_device(pdev);
if (err) {
dev_err(&pdev->dev, "failed to enable pci device.\n");
goto end;
}
/* set PCI host mastering */
pci_set_master(pdev);
/* pci request regions for mei driver */
err = pci_request_regions(pdev, KBUILD_MODNAME);
if (err) {
dev_err(&pdev->dev, "failed to get pci regions.\n");
goto disable_device;
}
/* allocates and initializes the mei dev structure */
dev = mei_device_init(pdev);
if (!dev) {
err = -ENOMEM;
goto release_regions;
}
/* mapping IO device memory */
dev->mem_addr = pci_iomap(pdev, 0, 0);
if (!dev->mem_addr) {
dev_err(&pdev->dev, "mapping I/O device memory failure.\n");
err = -ENOMEM;
goto free_device;
}
pci_enable_msi(pdev);

/* request and enable interrupt */
if (pci_dev_msi_enabled(pdev))
err = request_threaded_irq(pdev->irq,
NULL,
mei_interrupt_thread_handler,
IRQF_ONESHOT, KBUILD_MODNAME, dev);
else
err = request_threaded_irq(pdev->irq,
mei_interrupt_quick_handler,
mei_interrupt_thread_handler,
IRQF_SHARED, KBUILD_MODNAME, dev);

if (err) {
dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n",
pdev->irq);
goto disable_msi;
}

if (mei_hw_init(dev)) {
dev_err(&pdev->dev, "init hw failure.\n");
err = -ENODEV;
goto release_irq;
}

err = misc_register(&mei_misc_device);
if (err)
goto release_irq;

mei_pdev = pdev;
pci_set_drvdata(pdev, dev);


schedule_delayed_work(&dev->timer_work, HZ);

mutex_unlock(&mei_mutex);

pr_debug("initialization successful.\n");

return 0;

release_irq:
mei_disable_interrupts(dev);
flush_scheduled_work();
free_irq(pdev->irq, dev);
disable_msi:
pci_disable_msi(pdev);
pci_iounmap(pdev, dev->mem_addr);
free_device:
kfree(dev);
release_regions:
pci_release_regions(pdev);
disable_device:
pci_disable_device(pdev);
end:
mutex_unlock(&mei_mutex);
dev_err(&pdev->dev, "initialization failed.\n");
return err;
mei_misc_device.parent = dev;
return misc_register(&mei_misc_device);
}

/**
* mei_remove - Device Removal Routine
*
* @pdev: PCI device structure
*
* mei_remove is called by the PCI subsystem to alert the driver
* that it should release a PCI device.
*/
static void mei_remove(struct pci_dev *pdev)
void mei_deregister(void)
{
struct mei_device *dev;

if (mei_pdev != pdev)
return;

dev = pci_get_drvdata(pdev);
if (!dev)
return;

mutex_lock(&dev->device_lock);

cancel_delayed_work(&dev->timer_work);

mei_wd_stop(dev);

mei_pdev = NULL;

if (dev->iamthif_cl.state == MEI_FILE_CONNECTED) {
dev->iamthif_cl.state = MEI_FILE_DISCONNECTING;
mei_cl_disconnect(&dev->iamthif_cl);
}
if (dev->wd_cl.state == MEI_FILE_CONNECTED) {
dev->wd_cl.state = MEI_FILE_DISCONNECTING;
mei_cl_disconnect(&dev->wd_cl);
}

/* Unregistering watchdog device */
mei_watchdog_unregister(dev);

/* remove entry if already in list */
dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n");

if (dev->open_handle_count > 0)
dev->open_handle_count--;
mei_cl_unlink(&dev->wd_cl);

if (dev->open_handle_count > 0)
dev->open_handle_count--;
mei_cl_unlink(&dev->iamthif_cl);

dev->iamthif_current_cb = NULL;
dev->me_clients_num = 0;

mutex_unlock(&dev->device_lock);

flush_scheduled_work();

/* disable interrupts */
mei_disable_interrupts(dev);

free_irq(pdev->irq, dev);
pci_disable_msi(pdev);
pci_set_drvdata(pdev, NULL);

if (dev->mem_addr)
pci_iounmap(pdev, dev->mem_addr);

kfree(dev);

pci_release_regions(pdev);
pci_disable_device(pdev);

misc_deregister(&mei_misc_device);
mei_misc_device.parent = NULL;
}
#ifdef CONFIG_PM
static int mei_pci_suspend(struct device *device)
{
struct pci_dev *pdev = to_pci_dev(device);
struct mei_device *dev = pci_get_drvdata(pdev);
int err;

if (!dev)
return -ENODEV;
mutex_lock(&dev->device_lock);

cancel_delayed_work(&dev->timer_work);

/* Stop watchdog if exists */
err = mei_wd_stop(dev);
/* Set new mei state */
if (dev->dev_state == MEI_DEV_ENABLED ||
dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) {
dev->dev_state = MEI_DEV_POWER_DOWN;
mei_reset(dev, 0);
}
mutex_unlock(&dev->device_lock);

free_irq(pdev->irq, dev);
pci_disable_msi(pdev);

return err;
}

static int mei_pci_resume(struct device *device)
{
struct pci_dev *pdev = to_pci_dev(device);
struct mei_device *dev;
int err;

dev = pci_get_drvdata(pdev);
if (!dev)
return -ENODEV;

pci_enable_msi(pdev);

/* request and enable interrupt */
if (pci_dev_msi_enabled(pdev))
err = request_threaded_irq(pdev->irq,
NULL,
mei_interrupt_thread_handler,
IRQF_ONESHOT, KBUILD_MODNAME, dev);
else
err = request_threaded_irq(pdev->irq,
mei_interrupt_quick_handler,
mei_interrupt_thread_handler,
IRQF_SHARED, KBUILD_MODNAME, dev);

if (err) {
dev_err(&pdev->dev, "request_threaded_irq failed: irq = %d.\n",
pdev->irq);
return err;
}

mutex_lock(&dev->device_lock);
dev->dev_state = MEI_DEV_POWER_UP;
mei_reset(dev, 1);
mutex_unlock(&dev->device_lock);

/* Start timer if stopped in suspend */
schedule_delayed_work(&dev->timer_work, HZ);

return err;
}
static SIMPLE_DEV_PM_OPS(mei_pm_ops, mei_pci_suspend, mei_pci_resume);
#define MEI_PM_OPS (&mei_pm_ops)
#else
#define MEI_PM_OPS NULL
#endif /* CONFIG_PM */
/*
* PCI driver structure
*/
static struct pci_driver mei_driver = {
.name = KBUILD_MODNAME,
.id_table = mei_pci_tbl,
.probe = mei_probe,
.remove = mei_remove,
.shutdown = mei_remove,
.driver.pm = MEI_PM_OPS,
};

module_pci_driver(mei_driver);

MODULE_AUTHOR("Intel Corporation");
MODULE_DESCRIPTION("Intel(R) Management Engine Interface");
MODULE_LICENSE("GPL v2");
Loading

0 comments on commit 2703d4b

Please sign in to comment.