1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <linux/kernel.h>
27#include <linux/types.h>
28#include <linux/pci.h>
29#include <linux/pci-acpi.h>
30#include <linux/acpi.h>
31#include <linux/pm_runtime.h>
32#include <acpi/acpi_bus.h>
33#include <acpi/acpi_drivers.h>
34
35#define _COMPONENT ACPI_PCI_COMPONENT
36ACPI_MODULE_NAME("pci_bind");
37
38static int acpi_pci_unbind(struct acpi_device *device)
39{
40 struct pci_dev *dev;
41
42 dev = acpi_get_pci_dev(device->handle);
43 if (!dev)
44 goto out;
45
46 device_set_run_wake(&dev->dev, false);
47 pci_acpi_remove_pm_notifier(device);
48
49 if (!dev->subordinate)
50 goto out;
51
52 acpi_pci_irq_del_prt(dev->subordinate);
53
54 device->ops.bind = NULL;
55 device->ops.unbind = NULL;
56
57out:
58 pci_dev_put(dev);
59 return 0;
60}
61
62static int acpi_pci_bind(struct acpi_device *device)
63{
64 acpi_status status;
65 acpi_handle handle;
66 struct pci_bus *bus;
67 struct pci_dev *dev;
68
69 dev = acpi_get_pci_dev(device->handle);
70 if (!dev)
71 return 0;
72
73 pci_acpi_add_pm_notifier(device, dev);
74 if (device->wakeup.flags.run_wake)
75 device_set_run_wake(&dev->dev, true);
76
77
78
79
80
81 if (dev->subordinate) {
82 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
83 "Device %04x:%02x:%02x.%d is a PCI bridge\n",
84 pci_domain_nr(dev->bus), dev->bus->number,
85 PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)));
86 device->ops.bind = acpi_pci_bind;
87 device->ops.unbind = acpi_pci_unbind;
88 }
89
90
91
92
93
94
95
96
97
98 status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
99 if (ACPI_FAILURE(status))
100 goto out;
101
102 if (dev->subordinate)
103 bus = dev->subordinate;
104 else
105 bus = dev->bus;
106
107 acpi_pci_irq_add_prt(device->handle, bus);
108
109out:
110 pci_dev_put(dev);
111 return 0;
112}
113
114int acpi_pci_bind_root(struct acpi_device *device)
115{
116 device->ops.bind = acpi_pci_bind;
117 device->ops.unbind = acpi_pci_unbind;
118
119 return 0;
120}
121