aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/host-bridge.c15
-rw-r--r--drivers/pci/pci.h2
-rw-r--r--drivers/pci/probe.c66
-rw-r--r--include/linux/pci.h4
4 files changed, 39 insertions, 48 deletions
diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c
index c49a1c482cfb..122df80592c3 100644
--- a/drivers/pci/host-bridge.c
+++ b/drivers/pci/host-bridge.c
@@ -9,13 +9,6 @@
9 9
10#include "pci.h" 10#include "pci.h"
11 11
12static LIST_HEAD(pci_host_bridges);
13
14void add_to_pci_host_bridges(struct pci_host_bridge *bridge)
15{
16 list_add_tail(&bridge->list, &pci_host_bridges);
17}
18
19static struct pci_bus *find_pci_root_bus(struct pci_dev *dev) 12static struct pci_bus *find_pci_root_bus(struct pci_dev *dev)
20{ 13{
21 struct pci_bus *bus; 14 struct pci_bus *bus;
@@ -30,14 +23,8 @@ static struct pci_bus *find_pci_root_bus(struct pci_dev *dev)
30static struct pci_host_bridge *find_pci_host_bridge(struct pci_dev *dev) 23static struct pci_host_bridge *find_pci_host_bridge(struct pci_dev *dev)
31{ 24{
32 struct pci_bus *bus = find_pci_root_bus(dev); 25 struct pci_bus *bus = find_pci_root_bus(dev);
33 struct pci_host_bridge *bridge;
34
35 list_for_each_entry(bridge, &pci_host_bridges, list) {
36 if (bridge->bus == bus)
37 return bridge;
38 }
39 26
40 return NULL; 27 return to_pci_host_bridge(bus->bridge);
41} 28}
42 29
43static bool resource_contains(struct resource *res1, struct resource *res2) 30static bool resource_contains(struct resource *res1, struct resource *res2)
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index c695a92cca13..e4943479b234 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -231,8 +231,6 @@ static inline int pci_ari_enabled(struct pci_bus *bus)
231void pci_reassigndev_resource_alignment(struct pci_dev *dev); 231void pci_reassigndev_resource_alignment(struct pci_dev *dev);
232extern void pci_disable_bridge_window(struct pci_dev *dev); 232extern void pci_disable_bridge_window(struct pci_dev *dev);
233 233
234void add_to_pci_host_bridges(struct pci_host_bridge *bridge);
235
236/* Single Root I/O Virtualization */ 234/* Single Root I/O Virtualization */
237struct pci_sriov { 235struct pci_sriov {
238 int pos; /* capability position */ 236 int pos; /* capability position */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index bcea52b90e0d..8d291ee15257 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -422,6 +422,19 @@ static struct pci_bus * pci_alloc_bus(void)
422 return b; 422 return b;
423} 423}
424 424
425static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
426{
427 struct pci_host_bridge *bridge;
428
429 bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
430 if (bridge) {
431 INIT_LIST_HEAD(&bridge->windows);
432 bridge->bus = b;
433 }
434
435 return bridge;
436}
437
425static unsigned char pcix_bus_speed[] = { 438static unsigned char pcix_bus_speed[] = {
426 PCI_SPEED_UNKNOWN, /* 0 */ 439 PCI_SPEED_UNKNOWN, /* 0 */
427 PCI_SPEED_66MHz_PCIX, /* 1 */ 440 PCI_SPEED_66MHz_PCIX, /* 1 */
@@ -1122,7 +1135,13 @@ int pci_cfg_space_size(struct pci_dev *dev)
1122 1135
1123static void pci_release_bus_bridge_dev(struct device *dev) 1136static void pci_release_bus_bridge_dev(struct device *dev)
1124{ 1137{
1125 kfree(dev); 1138 struct pci_host_bridge *bridge = to_pci_host_bridge(dev);
1139
1140 /* TODO: need to free window->res */
1141
1142 pci_free_resource_list(&bridge->windows);
1143
1144 kfree(bridge);
1126} 1145}
1127 1146
1128struct pci_dev *alloc_pci_dev(void) 1147struct pci_dev *alloc_pci_dev(void)
@@ -1571,28 +1590,19 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
1571 int error; 1590 int error;
1572 struct pci_host_bridge *bridge; 1591 struct pci_host_bridge *bridge;
1573 struct pci_bus *b, *b2; 1592 struct pci_bus *b, *b2;
1574 struct device *dev;
1575 struct pci_host_bridge_window *window, *n; 1593 struct pci_host_bridge_window *window, *n;
1576 struct resource *res; 1594 struct resource *res;
1577 resource_size_t offset; 1595 resource_size_t offset;
1578 char bus_addr[64]; 1596 char bus_addr[64];
1579 char *fmt; 1597 char *fmt;
1580 1598
1581 bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
1582 if (!bridge)
1583 return NULL;
1584 1599
1585 b = pci_alloc_bus(); 1600 b = pci_alloc_bus();
1586 if (!b) 1601 if (!b)
1587 goto err_bus; 1602 return NULL;
1588
1589 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1590 if (!dev)
1591 goto err_dev;
1592 1603
1593 b->sysdata = sysdata; 1604 b->sysdata = sysdata;
1594 b->ops = ops; 1605 b->ops = ops;
1595
1596 b2 = pci_find_bus(pci_domain_nr(b), bus); 1606 b2 = pci_find_bus(pci_domain_nr(b), bus);
1597 if (b2) { 1607 if (b2) {
1598 /* If we already got to this bus through a different bridge, ignore it */ 1608 /* If we already got to this bus through a different bridge, ignore it */
@@ -1600,13 +1610,17 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
1600 goto err_out; 1610 goto err_out;
1601 } 1611 }
1602 1612
1603 dev->parent = parent; 1613 bridge = pci_alloc_host_bridge(b);
1604 dev->release = pci_release_bus_bridge_dev; 1614 if (!bridge)
1605 dev_set_name(dev, "pci%04x:%02x", pci_domain_nr(b), bus); 1615 goto err_out;
1606 error = device_register(dev); 1616
1617 bridge->dev.parent = parent;
1618 bridge->dev.release = pci_release_bus_bridge_dev;
1619 dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
1620 error = device_register(&bridge->dev);
1607 if (error) 1621 if (error)
1608 goto dev_reg_err; 1622 goto bridge_dev_reg_err;
1609 b->bridge = get_device(dev); 1623 b->bridge = get_device(&bridge->dev);
1610 device_enable_async_suspend(b->bridge); 1624 device_enable_async_suspend(b->bridge);
1611 pci_set_bus_of_node(b); 1625 pci_set_bus_of_node(b);
1612 1626
@@ -1625,9 +1639,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
1625 1639
1626 b->number = b->secondary = bus; 1640 b->number = b->secondary = bus;
1627 1641
1628 bridge->bus = b;
1629 INIT_LIST_HEAD(&bridge->windows);
1630
1631 if (parent) 1642 if (parent)
1632 dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev)); 1643 dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev));
1633 else 1644 else
@@ -1653,25 +1664,18 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
1653 } 1664 }
1654 1665
1655 down_write(&pci_bus_sem); 1666 down_write(&pci_bus_sem);
1656 add_to_pci_host_bridges(bridge);
1657 list_add_tail(&b->node, &pci_root_buses); 1667 list_add_tail(&b->node, &pci_root_buses);
1658 up_write(&pci_bus_sem); 1668 up_write(&pci_bus_sem);
1659 1669
1660 return b; 1670 return b;
1661 1671
1662class_dev_reg_err: 1672class_dev_reg_err:
1663 device_unregister(dev); 1673 put_device(&bridge->dev);
1664dev_reg_err: 1674 device_unregister(&bridge->dev);
1665 down_write(&pci_bus_sem); 1675bridge_dev_reg_err:
1666 list_del(&bridge->list); 1676 kfree(bridge);
1667 list_del(&b->node);
1668 up_write(&pci_bus_sem);
1669err_out: 1677err_out:
1670 kfree(dev);
1671err_dev:
1672 kfree(b); 1678 kfree(b);
1673err_bus:
1674 kfree(bridge);
1675 return NULL; 1679 return NULL;
1676} 1680}
1677 1681
diff --git a/include/linux/pci.h b/include/linux/pci.h
index e444f5b49118..8f4f29d2b606 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -375,11 +375,13 @@ struct pci_host_bridge_window {
375}; 375};
376 376
377struct pci_host_bridge { 377struct pci_host_bridge {
378 struct list_head list; 378 struct device dev;
379 struct pci_bus *bus; /* root bus */ 379 struct pci_bus *bus; /* root bus */
380 struct list_head windows; /* pci_host_bridge_windows */ 380 struct list_head windows; /* pci_host_bridge_windows */
381}; 381};
382 382
383#define to_pci_host_bridge(n) container_of(n, struct pci_host_bridge, dev)
384
383/* 385/*
384 * The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond 386 * The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond
385 * to P2P or CardBus bridge windows) go in a table. Additional ones (for 387 * to P2P or CardBus bridge windows) go in a table. Additional ones (for