aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/rpaphp_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/hotplug/rpaphp_pci.c')
-rw-r--r--drivers/pci/hotplug/rpaphp_pci.c72
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
33struct pci_dev *rpaphp_find_pci_dev(struct device_node *dn) 33static 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
48struct 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
67struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn) 52static 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
74EXPORT_SYMBOL_GPL(rpaphp_find_pci_dev);
75
76int rpaphp_claim_resource(struct pci_dev *dev, int resource) 60int 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 */
138int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value) 122int 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 }
175exit: 149exit:
@@ -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