Skip to content

Commit 4f53509

Browse files
Yinghai Lubjorn-helgaas
authored andcommitted
PCI: Put pci_dev in device tree as early as possible
We want to put pci_dev structs in the device tree as soon as possible so for_each_pci_dev() iteration will not miss them, but driver attachment needs to be delayed until after pci_assign_unassigned_resources() to make sure all devices have resources assigned first. This patch moves device registering from pci_bus_add_devices() to pci_device_add(), which happens earlier, leaving driver attachment in pci_bus_add_devices(). It also removes unattached child bus handling in pci_bus_add_devices(). That's not needed because child bus via pci_add_new_bus() is already in parent bus children list. [bhelgaas: changelog] Signed-off-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 58d9a38 commit 4f53509

File tree

4 files changed

+41
-82
lines changed

4 files changed

+41
-82
lines changed

drivers/pci/bus.c

Lines changed: 12 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -161,73 +161,35 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
161161
void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { }
162162

163163
/**
164-
* pci_bus_add_device - add a single device
164+
* pci_bus_add_device - start driver for a single device
165165
* @dev: device to add
166166
*
167-
* This adds a single pci device to the global
168-
* device list and adds sysfs and procfs entries
167+
* This adds add sysfs entries and start device drivers
169168
*/
170169
int pci_bus_add_device(struct pci_dev *dev)
171170
{
172171
int retval;
173172

174-
pci_fixup_device(pci_fixup_final, dev);
175-
176-
retval = pcibios_add_device(dev);
177-
if (retval)
178-
return retval;
179-
180-
dev->match_driver = false;
181-
retval = device_add(&dev->dev);
182-
if (retval)
183-
return retval;
173+
/*
174+
* Can not put in pci_device_add yet because resources
175+
* are not assigned yet for some devices.
176+
*/
177+
pci_create_sysfs_dev_files(dev);
184178

185179
dev->match_driver = true;
186180
retval = device_attach(&dev->dev);
187181
WARN_ON(retval < 0);
188182

189183
dev->is_added = 1;
190-
pci_proc_attach_device(dev);
191-
pci_create_sysfs_dev_files(dev);
192-
return 0;
193-
}
194-
195-
/**
196-
* pci_bus_add_child - add a child bus
197-
* @bus: bus to add
198-
*
199-
* This adds sysfs entries for a single bus
200-
*/
201-
int pci_bus_add_child(struct pci_bus *bus)
202-
{
203-
int retval;
204-
205-
if (bus->bridge)
206-
bus->dev.parent = bus->bridge;
207-
208-
retval = device_register(&bus->dev);
209-
if (retval)
210-
return retval;
211184

212-
bus->is_added = 1;
213-
214-
/* Create legacy_io and legacy_mem files for this bus */
215-
pci_create_legacy_files(bus);
216-
217-
return retval;
185+
return 0;
218186
}
219187

220188
/**
221-
* pci_bus_add_devices - insert newly discovered PCI devices
189+
* pci_bus_add_devices - start driver for PCI devices
222190
* @bus: bus to check for new devices
223191
*
224-
* Add newly discovered PCI devices (which are on the bus->devices
225-
* list) to the global PCI device list, add the sysfs and procfs
226-
* entries. Where a bridge is found, add the discovered bus to
227-
* the parents list of child buses, and recurse (breadth-first
228-
* to be compatible with 2.4)
229-
*
230-
* Call hotplug for each new devices.
192+
* Start driver for PCI devices and add some sysfs entries.
231193
*/
232194
void pci_bus_add_devices(const struct pci_bus *bus)
233195
{
@@ -240,36 +202,20 @@ void pci_bus_add_devices(const struct pci_bus *bus)
240202
if (dev->is_added)
241203
continue;
242204
retval = pci_bus_add_device(dev);
243-
if (retval)
244-
dev_err(&dev->dev, "Error adding device, continuing\n");
245205
}
246206

247207
list_for_each_entry(dev, &bus->devices, bus_list) {
248208
BUG_ON(!dev->is_added);
249209

250210
child = dev->subordinate;
251-
/*
252-
* If there is an unattached subordinate bus, attach
253-
* it and then scan for unattached PCI devices.
254-
*/
211+
255212
if (!child)
256213
continue;
257-
if (list_empty(&child->node)) {
258-
down_write(&pci_bus_sem);
259-
list_add_tail(&child->node, &dev->bus->children);
260-
up_write(&pci_bus_sem);
261-
}
262214
pci_bus_add_devices(child);
263215

264-
/*
265-
* register the bus with sysfs as the parent is now
266-
* properly registered.
267-
*/
268216
if (child->is_added)
269217
continue;
270-
retval = pci_bus_add_child(child);
271-
if (retval)
272-
dev_err(&dev->dev, "Error adding bus, continuing\n");
218+
child->is_added = 1;
273219
}
274220
}
275221

drivers/pci/iov.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,7 @@ static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr)
4848
return NULL;
4949

5050
pci_bus_insert_busn_res(child, busnr, busnr);
51-
child->dev.parent = bus->bridge;
52-
rc = pci_bus_add_child(child);
53-
if (rc) {
54-
pci_remove_bus(child);
55-
return NULL;
56-
}
51+
bus->is_added = 1;
5752

5853
return child;
5954
}
@@ -123,8 +118,6 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)
123118
virtfn->is_virtfn = 1;
124119

125120
rc = pci_bus_add_device(virtfn);
126-
if (rc)
127-
goto failed1;
128121
sprintf(buf, "virtfn%u", id);
129122
rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
130123
if (rc)

drivers/pci/pci.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,6 @@ extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
203203
struct resource *res, unsigned int reg);
204204
extern int pci_resource_bar(struct pci_dev *dev, int resno,
205205
enum pci_bar_type *type);
206-
extern int pci_bus_add_child(struct pci_bus *bus);
207206
extern void pci_enable_ari(struct pci_dev *dev);
208207
/**
209208
* pci_ari_enabled - query ARI forwarding status

drivers/pci/probe.c

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
623623
{
624624
struct pci_bus *child;
625625
int i;
626+
int ret;
626627

627628
/*
628629
* Allocate a new bus, and inherit stuff from the parent..
@@ -637,8 +638,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
637638
child->bus_flags = parent->bus_flags;
638639

639640
/* initialize some portions of the bus device, but don't register it
640-
* now as the parent is not properly set up yet. This device will get
641-
* registered later in pci_bus_add_devices()
641+
* now as the parent is not properly set up yet.
642642
*/
643643
child->dev.class = &pcibus_class;
644644
dev_set_name(&child->dev, "%04x:%02x", pci_domain_nr(child), busnr);
@@ -651,11 +651,14 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
651651
child->primary = parent->busn_res.start;
652652
child->busn_res.end = 0xff;
653653

654-
if (!bridge)
655-
return child;
654+
if (!bridge) {
655+
child->dev.parent = parent->bridge;
656+
goto add_dev;
657+
}
656658

657659
child->self = bridge;
658660
child->bridge = get_device(&bridge->dev);
661+
child->dev.parent = child->bridge;
659662
pci_set_bus_of_node(child);
660663
pci_set_bus_speed(child);
661664

@@ -666,6 +669,13 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
666669
}
667670
bridge->subordinate = child;
668671

672+
add_dev:
673+
ret = device_register(&child->dev);
674+
WARN_ON(ret < 0);
675+
676+
/* Create legacy_io and legacy_mem files for this bus */
677+
pci_create_legacy_files(child);
678+
669679
return child;
670680
}
671681

@@ -1296,6 +1306,8 @@ static void pci_init_capabilities(struct pci_dev *dev)
12961306

12971307
void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
12981308
{
1309+
int ret;
1310+
12991311
device_initialize(&dev->dev);
13001312
dev->dev.release = pci_release_dev;
13011313

@@ -1326,6 +1338,17 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
13261338
down_write(&pci_bus_sem);
13271339
list_add_tail(&dev->bus_list, &bus->devices);
13281340
up_write(&pci_bus_sem);
1341+
1342+
pci_fixup_device(pci_fixup_final, dev);
1343+
ret = pcibios_add_device(dev);
1344+
WARN_ON(ret < 0);
1345+
1346+
/* Notifier could use PCI capabilities */
1347+
dev->match_driver = false;
1348+
ret = device_add(&dev->dev);
1349+
WARN_ON(ret < 0);
1350+
1351+
pci_proc_attach_device(dev);
13291352
}
13301353

13311354
struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn)
@@ -1644,13 +1667,13 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
16441667
char bus_addr[64];
16451668
char *fmt;
16461669

1647-
16481670
b = pci_alloc_bus();
16491671
if (!b)
16501672
return NULL;
16511673

16521674
b->sysdata = sysdata;
16531675
b->ops = ops;
1676+
b->number = b->busn_res.start = bus;
16541677
b2 = pci_find_bus(pci_domain_nr(b), bus);
16551678
if (b2) {
16561679
/* If we already got to this bus through a different bridge, ignore it */
@@ -1685,8 +1708,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
16851708
/* Create legacy_io and legacy_mem files for this bus */
16861709
pci_create_legacy_files(b);
16871710

1688-
b->number = b->busn_res.start = bus;
1689-
16901711
if (parent)
16911712
dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev));
16921713
else

0 commit comments

Comments
 (0)