diff options
Diffstat (limited to 'drivers/pci/pcie/portdrv_pci.c')
-rw-r--r-- | drivers/pci/pcie/portdrv_pci.c | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c new file mode 100644 index 000000000000..3184843c3649 --- /dev/null +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -0,0 +1,122 @@ | |||
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 | pcie_port_device_remove(dev); | ||
67 | } | ||
68 | |||
69 | #ifdef CONFIG_PM | ||
70 | static int pcie_portdrv_suspend (struct pci_dev *dev, u32 state) | ||
71 | { | ||
72 | return pcie_port_device_suspend(dev, state); | ||
73 | } | ||
74 | |||
75 | static int pcie_portdrv_resume (struct pci_dev *dev) | ||
76 | { | ||
77 | return pcie_port_device_resume(dev); | ||
78 | } | ||
79 | #endif | ||
80 | |||
81 | /* | ||
82 | * LINUX Device Driver Model | ||
83 | */ | ||
84 | static const struct pci_device_id port_pci_ids[] = { { | ||
85 | /* handle any PCI-Express port */ | ||
86 | PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0), | ||
87 | }, { /* end: all zeroes */ } | ||
88 | }; | ||
89 | MODULE_DEVICE_TABLE(pci, port_pci_ids); | ||
90 | |||
91 | static struct pci_driver pcie_portdrv = { | ||
92 | .name = (char *)device_name, | ||
93 | .id_table = &port_pci_ids[0], | ||
94 | |||
95 | .probe = pcie_portdrv_probe, | ||
96 | .remove = pcie_portdrv_remove, | ||
97 | |||
98 | #ifdef CONFIG_PM | ||
99 | .suspend = pcie_portdrv_suspend, | ||
100 | .resume = pcie_portdrv_resume, | ||
101 | #endif /* PM */ | ||
102 | }; | ||
103 | |||
104 | static int __init pcie_portdrv_init(void) | ||
105 | { | ||
106 | int retval = 0; | ||
107 | |||
108 | pcie_port_bus_register(); | ||
109 | retval = pci_register_driver(&pcie_portdrv); | ||
110 | if (retval) | ||
111 | pcie_port_bus_unregister(); | ||
112 | return retval; | ||
113 | } | ||
114 | |||
115 | static void __exit pcie_portdrv_exit(void) | ||
116 | { | ||
117 | pci_unregister_driver(&pcie_portdrv); | ||
118 | pcie_port_bus_unregister(); | ||
119 | } | ||
120 | |||
121 | module_init(pcie_portdrv_init); | ||
122 | module_exit(pcie_portdrv_exit); | ||