aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c35
-rw-r--r--drivers/pci/hotplug/rpaphp.h1
-rw-r--r--drivers/pci/hotplug/rpaphp_pci.c72
3 files changed, 47 insertions, 61 deletions
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index 7f868edaa72d..2ee7eb513e6c 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -165,6 +165,20 @@ static int pci_add_secondary_bus(struct device_node *dn,
165 return 0; 165 return 0;
166} 166}
167 167
168static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent,
169 struct device_node *dev_dn)
170{
171 struct pci_dev *tmp = NULL;
172 struct device_node *child_dn;
173
174 list_for_each_entry(tmp, &parent->devices, bus_list) {
175 child_dn = pci_device_to_OF_node(tmp);
176 if (child_dn == dev_dn)
177 return tmp;
178 }
179 return NULL;
180}
181
168static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) 182static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
169{ 183{
170 struct pci_controller *hose = dn->phb; 184 struct pci_controller *hose = dn->phb;
@@ -180,21 +194,18 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
180 pci_bus_add_devices(hose->bus); 194 pci_bus_add_devices(hose->bus);
181 195
182 /* Confirm new bridge dev was created */ 196 /* Confirm new bridge dev was created */
183 dev = rpaphp_find_pci_dev(dn); 197 dev = dlpar_find_new_dev(hose->bus, dn);
184 if (!dev) { 198 if (dev) {
185 printk(KERN_ERR "%s: failed to add pci device\n", __FUNCTION__); 199 if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
186 return NULL; 200 printk(KERN_ERR "%s: unexpected header type %d\n",
187 } 201 __FUNCTION__, dev->hdr_type);
202 return NULL;
203 }
188 204
189 if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { 205 if (pci_add_secondary_bus(dn, dev))
190 printk(KERN_ERR "%s: unexpected header type %d\n", 206 return NULL;
191 __FUNCTION__, dev->hdr_type);
192 return NULL;
193 } 207 }
194 208
195 if (pci_add_secondary_bus(dn, dev))
196 return NULL;
197
198 return dev; 209 return dev;
199} 210}
200 211
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
index 9f050fde80c2..8ecff0b950e8 100644
--- a/drivers/pci/hotplug/rpaphp.h
+++ b/drivers/pci/hotplug/rpaphp.h
@@ -93,7 +93,6 @@ extern int num_slots;
93/* function prototypes */ 93/* function prototypes */
94 94
95/* rpaphp_pci.c */ 95/* rpaphp_pci.c */
96extern struct pci_dev *rpaphp_find_pci_dev(struct device_node *dn);
97extern int rpaphp_claim_resource(struct pci_dev *dev, int resource); 96extern int rpaphp_claim_resource(struct pci_dev *dev, int resource);
98extern int rpaphp_enable_pci_slot(struct slot *slot); 97extern int rpaphp_enable_pci_slot(struct slot *slot);
99extern int register_pci_slot(struct slot *slot); 98extern int register_pci_slot(struct slot *slot);
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