aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2012-04-02 21:31:53 -0400
committerBjorn Helgaas <bhelgaas@google.com>2012-04-30 15:53:42 -0400
commit7b54366358008241f88228f02cc80ab352265eac (patch)
tree4de6ae8ce83afabf1b4405cba6895b09d1bc790d /drivers/pci
parent459f58ce51e2e11235b7bb4b1732ebf3c17d86f7 (diff)
PCI: add generic device into pci_host_bridge struct
Use that device for pci_root_bus bridge pointer. Use pci_release_bus_bridge_dev() to release allocated pci_host_bridge in remove path. Use root bus bridge pointer to get host bridge pointer instead of searching host bridge list. That leaves the host bridge list unused, so remove it. Signed-off-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/host-bridge.c15
-rw-r--r--drivers/pci/pci.h2
-rw-r--r--drivers/pci/probe.c66
3 files changed, 36 insertions, 47 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