- patches.fixes/patch-2.6.11-rc1: 2.6.11-rc1.
[linux-flexiantxendom0-3.2.10.git] / drivers / pci / pcie / portdrv_pci.c
1 /*
2  * File:        portdrv_pci.c
3  * Purpose:     PCI Express Port Bus Driver
4  *
5  * Copyright (C) 2004 Intel
6  * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
7  */
8
9 #include <linux/module.h>
10 #include <linux/pci.h>
11 #include <linux/kernel.h>
12 #include <linux/errno.h>
13 #include <linux/pm.h>
14 #include <linux/init.h>
15 #include <linux/pcieport_if.h>
16
17 #include "portdrv.h"
18
19 /*
20  * Version Information
21  */
22 #define DRIVER_VERSION "v1.0"
23 #define DRIVER_AUTHOR "tom.l.nguyen@intel.com"
24 #define DRIVER_DESC "PCIE Port Bus Driver"
25 MODULE_AUTHOR(DRIVER_AUTHOR);
26 MODULE_DESCRIPTION(DRIVER_DESC);
27 MODULE_LICENSE("GPL");
28
29 /* global data */
30 static const char device_name[] = "pcieport-driver";
31
32 /*
33  * pcie_portdrv_probe - Probe PCI-Express port devices
34  * @dev: PCI-Express port device being probed
35  *
36  * If detected invokes the pcie_port_device_register() method for 
37  * this port device.
38  *
39  */
40 static int __devinit pcie_portdrv_probe (struct pci_dev *dev, 
41                                 const struct pci_device_id *id )
42 {
43         int                     status;
44
45         status = pcie_port_device_probe(dev);
46         if (status)
47                 return status;
48
49         if (pci_enable_device(dev) < 0) 
50                 return -ENODEV;
51         
52         pci_set_master(dev);
53         if (!dev->irq) {
54                 printk(KERN_WARNING 
55                 "%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n", 
56                 __FUNCTION__, dev->device, dev->vendor);
57         }
58         if (pcie_port_device_register(dev)) 
59                 return -ENOMEM;
60
61         return 0;
62 }
63
64 static void pcie_portdrv_remove (struct pci_dev *dev)
65 {
66         struct pcie_device *pciedev;
67
68         pciedev = (struct pcie_device *)pci_get_drvdata(dev);
69         if (pciedev) {
70                 pcie_port_device_remove(pciedev);
71                 pci_set_drvdata(dev, NULL); 
72         }
73 }
74
75 #ifdef CONFIG_PM
76 static int pcie_portdrv_suspend (struct pci_dev *dev, u32 state)
77 {
78         struct pcie_device *pciedev;
79         
80         pciedev = (struct pcie_device *)pci_get_drvdata(dev);
81         if (pciedev) 
82                 pcie_port_device_suspend(pciedev, state);
83         return 0;
84 }
85
86 static int pcie_portdrv_resume (struct pci_dev *dev)
87 {
88         struct pcie_device *pciedev;
89         
90         pciedev = (struct pcie_device *)pci_get_drvdata(dev);
91         if (pciedev) 
92                 pcie_port_device_resume(pciedev);
93         return 0;
94 }
95 #endif
96
97 /*
98  * LINUX Device Driver Model
99  */
100 static const struct pci_device_id port_pci_ids[] = { {
101         /* handle any PCI-Express port */
102         PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
103         }, { /* end: all zeroes */ }
104 };
105 MODULE_DEVICE_TABLE(pci, port_pci_ids);
106
107 static struct pci_driver pcie_portdrv = {
108         .name           = (char *)device_name,
109         .id_table       = &port_pci_ids[0],
110
111         .probe          = pcie_portdrv_probe,
112         .remove         = pcie_portdrv_remove,
113
114 #ifdef  CONFIG_PM
115         .suspend        = pcie_portdrv_suspend,
116         .resume         = pcie_portdrv_resume,
117 #endif  /* PM */
118 };
119
120 static int __init pcie_portdrv_init(void)
121 {
122         int retval = 0;
123
124         pcie_port_bus_register();
125         retval = pci_module_init(&pcie_portdrv);
126         if (retval)
127                 pcie_port_bus_unregister();
128         return retval;
129 }
130
131 static void __exit pcie_portdrv_exit(void) 
132 {
133         pci_unregister_driver(&pcie_portdrv);
134         pcie_port_bus_unregister();
135 }
136
137 module_init(pcie_portdrv_init);
138 module_exit(pcie_portdrv_exit);