diff options
Diffstat (limited to 'drivers/pci/hotplug/rpaphp_pci.c')
-rw-r--r-- | drivers/pci/hotplug/rpaphp_pci.c | 72 |
1 files changed, 24 insertions, 48 deletions
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 54fff5fb0094..30a892ca4b37 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c | |||
@@ -30,22 +30,7 @@ | |||
30 | 30 | ||
31 | #include "rpaphp.h" | 31 | #include "rpaphp.h" |
32 | 32 | ||
33 | struct pci_dev *rpaphp_find_pci_dev(struct device_node *dn) | 33 | static struct pci_bus *find_bus_among_children(struct pci_bus *bus, |
34 | { | ||
35 | struct pci_dev *dev = NULL; | ||
36 | char bus_id[BUS_ID_SIZE]; | ||
37 | |||
38 | sprintf(bus_id, "%04x:%02x:%02x.%d", dn->phb->global_number, | ||
39 | dn->busno, PCI_SLOT(dn->devfn), PCI_FUNC(dn->devfn)); | ||
40 | for_each_pci_dev(dev) { | ||
41 | if (!strcmp(pci_name(dev), bus_id)) { | ||
42 | break; | ||
43 | } | ||
44 | } | ||
45 | return dev; | ||
46 | } | ||
47 | |||
48 | struct pci_bus *find_bus_among_children(struct pci_bus *bus, | ||
49 | struct device_node *dn) | 34 | struct device_node *dn) |
50 | { | 35 | { |
51 | struct pci_bus *child = NULL; | 36 | struct pci_bus *child = NULL; |
@@ -64,15 +49,14 @@ struct pci_bus *find_bus_among_children(struct pci_bus *bus, | |||
64 | return child; | 49 | return child; |
65 | } | 50 | } |
66 | 51 | ||
67 | struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn) | 52 | static struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn) |
68 | { | 53 | { |
69 | BUG_ON(!dn->phb || !dn->phb->bus); | 54 | if (!dn->phb || !dn->phb->bus) |
55 | return NULL; | ||
70 | 56 | ||
71 | return find_bus_among_children(dn->phb->bus, dn); | 57 | return find_bus_among_children(dn->phb->bus, dn); |
72 | } | 58 | } |
73 | 59 | ||
74 | EXPORT_SYMBOL_GPL(rpaphp_find_pci_dev); | ||
75 | |||
76 | int rpaphp_claim_resource(struct pci_dev *dev, int resource) | 60 | int rpaphp_claim_resource(struct pci_dev *dev, int resource) |
77 | { | 61 | { |
78 | struct resource *res = &dev->resource[resource]; | 62 | struct resource *res = &dev->resource[resource]; |
@@ -137,9 +121,8 @@ static int rpaphp_get_sensor_state(struct slot *slot, int *state) | |||
137 | */ | 121 | */ |
138 | int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value) | 122 | int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value) |
139 | { | 123 | { |
124 | struct pci_bus *bus; | ||
140 | int state, rc; | 125 | int state, rc; |
141 | struct device_node *child_dn; | ||
142 | struct pci_dev *child_dev = NULL; | ||
143 | 126 | ||
144 | *value = NOT_VALID; | 127 | *value = NOT_VALID; |
145 | rc = rpaphp_get_sensor_state(slot, &state); | 128 | rc = rpaphp_get_sensor_state(slot, &state); |
@@ -156,20 +139,11 @@ int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value) | |||
156 | /* config/unconfig adapter */ | 139 | /* config/unconfig adapter */ |
157 | *value = slot->state; | 140 | *value = slot->state; |
158 | } else { | 141 | } else { |
159 | child_dn = slot->dn->child; | 142 | bus = rpaphp_find_pci_bus(slot->dn); |
160 | if (child_dn) | 143 | if (bus && !list_empty(&bus->devices)) |
161 | child_dev = rpaphp_find_pci_dev(child_dn); | 144 | *value = CONFIGURED; |
162 | 145 | else | |
163 | if (child_dev) | ||
164 | *value = CONFIGURED; | ||
165 | else if (!child_dn) | ||
166 | dbg("%s: %s is not valid OFDT node\n", | ||
167 | __FUNCTION__, slot->dn->full_name); | ||
168 | else { | ||
169 | err("%s: can't find pdev of adapter in slot[%s]\n", | ||
170 | __FUNCTION__, slot->dn->full_name); | ||
171 | *value = NOT_CONFIGURED; | 146 | *value = NOT_CONFIGURED; |
172 | } | ||
173 | } | 147 | } |
174 | } | 148 | } |
175 | exit: | 149 | exit: |
@@ -252,24 +226,26 @@ rpaphp_pci_config_slot(struct device_node *dn, struct pci_bus *bus) | |||
252 | int num; | 226 | int num; |
253 | 227 | ||
254 | dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name); | 228 | dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name); |
229 | if (!dn->child) | ||
230 | return NULL; | ||
255 | 231 | ||
256 | if (dn->child) { | 232 | slotno = PCI_SLOT(dn->child->devfn); |
257 | slotno = PCI_SLOT(dn->child->devfn); | ||
258 | 233 | ||
259 | /* pci_scan_slot should find all children */ | 234 | /* pci_scan_slot should find all children */ |
260 | num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); | 235 | num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); |
261 | if (num) { | 236 | if (num) { |
262 | rpaphp_fixup_new_pci_devices(bus, 1); | 237 | rpaphp_fixup_new_pci_devices(bus, 1); |
263 | pci_bus_add_devices(bus); | 238 | pci_bus_add_devices(bus); |
264 | } | 239 | } |
265 | dev = rpaphp_find_pci_dev(dn->child); | 240 | if (list_empty(&bus->devices)) { |
266 | if (!dev) { | 241 | err("%s: No new device found\n", __FUNCTION__); |
267 | err("No new device found\n"); | 242 | return NULL; |
268 | return NULL; | 243 | } |
269 | } | 244 | list_for_each_entry(dev, &bus->devices, bus_list) { |
270 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) | 245 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) |
271 | rpaphp_pci_config_bridge(dev); | 246 | rpaphp_pci_config_bridge(dev); |
272 | } | 247 | } |
248 | |||
273 | return dev; | 249 | return dev; |
274 | } | 250 | } |
275 | 251 | ||