mei: sperate interface and pci code into two files
[linux-2.6-block.git] / drivers / misc / mei / main.c
index 123c663509ef21f42f8cd85b21824754fae0d4d0..018623c9a8e16ab2dfb6ea29e9baaf2264f8116b 100644 (file)
 #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
  *
@@ -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;
 
@@ -787,7 +744,6 @@ static const struct file_operations mei_fops = {
        .llseek = no_llseek
 };
 
-
 /*
  * Misc Device Struct
  */
@@ -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");