diff options
Diffstat (limited to 'arch/powerpc/kernel/pci-common.c')
-rw-r--r-- | arch/powerpc/kernel/pci-common.c | 133 |
1 files changed, 122 insertions, 11 deletions
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 5a56e97c5ac0..e9f4840096b3 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -50,14 +50,14 @@ resource_size_t isa_mem_base; | |||
50 | unsigned int ppc_pci_flags = 0; | 50 | unsigned int ppc_pci_flags = 0; |
51 | 51 | ||
52 | 52 | ||
53 | static struct dma_mapping_ops *pci_dma_ops = &dma_direct_ops; | 53 | static struct dma_map_ops *pci_dma_ops = &dma_direct_ops; |
54 | 54 | ||
55 | void set_pci_dma_ops(struct dma_mapping_ops *dma_ops) | 55 | void set_pci_dma_ops(struct dma_map_ops *dma_ops) |
56 | { | 56 | { |
57 | pci_dma_ops = dma_ops; | 57 | pci_dma_ops = dma_ops; |
58 | } | 58 | } |
59 | 59 | ||
60 | struct dma_mapping_ops *get_pci_dma_ops(void) | 60 | struct dma_map_ops *get_pci_dma_ops(void) |
61 | { | 61 | { |
62 | return pci_dma_ops; | 62 | return pci_dma_ops; |
63 | } | 63 | } |
@@ -176,8 +176,6 @@ int pci_domain_nr(struct pci_bus *bus) | |||
176 | } | 176 | } |
177 | EXPORT_SYMBOL(pci_domain_nr); | 177 | EXPORT_SYMBOL(pci_domain_nr); |
178 | 178 | ||
179 | #ifdef CONFIG_PPC_OF | ||
180 | |||
181 | /* This routine is meant to be used early during boot, when the | 179 | /* This routine is meant to be used early during boot, when the |
182 | * PCI bus numbers have not yet been assigned, and you need to | 180 | * PCI bus numbers have not yet been assigned, and you need to |
183 | * issue PCI config cycles to an OF device. | 181 | * issue PCI config cycles to an OF device. |
@@ -210,17 +208,11 @@ static ssize_t pci_show_devspec(struct device *dev, | |||
210 | return sprintf(buf, "%s", np->full_name); | 208 | return sprintf(buf, "%s", np->full_name); |
211 | } | 209 | } |
212 | static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL); | 210 | static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL); |
213 | #endif /* CONFIG_PPC_OF */ | ||
214 | 211 | ||
215 | /* Add sysfs properties */ | 212 | /* Add sysfs properties */ |
216 | int pcibios_add_platform_entries(struct pci_dev *pdev) | 213 | int pcibios_add_platform_entries(struct pci_dev *pdev) |
217 | { | 214 | { |
218 | #ifdef CONFIG_PPC_OF | ||
219 | return device_create_file(&pdev->dev, &dev_attr_devspec); | 215 | return device_create_file(&pdev->dev, &dev_attr_devspec); |
220 | #else | ||
221 | return 0; | ||
222 | #endif /* CONFIG_PPC_OF */ | ||
223 | |||
224 | } | 216 | } |
225 | 217 | ||
226 | char __devinit *pcibios_setup(char *str) | 218 | char __devinit *pcibios_setup(char *str) |
@@ -1626,3 +1618,122 @@ void __devinit pcibios_setup_phb_resources(struct pci_controller *hose) | |||
1626 | 1618 | ||
1627 | } | 1619 | } |
1628 | 1620 | ||
1621 | /* | ||
1622 | * Null PCI config access functions, for the case when we can't | ||
1623 | * find a hose. | ||
1624 | */ | ||
1625 | #define NULL_PCI_OP(rw, size, type) \ | ||
1626 | static int \ | ||
1627 | null_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \ | ||
1628 | { \ | ||
1629 | return PCIBIOS_DEVICE_NOT_FOUND; \ | ||
1630 | } | ||
1631 | |||
1632 | static int | ||
1633 | null_read_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
1634 | int len, u32 *val) | ||
1635 | { | ||
1636 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
1637 | } | ||
1638 | |||
1639 | static int | ||
1640 | null_write_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
1641 | int len, u32 val) | ||
1642 | { | ||
1643 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
1644 | } | ||
1645 | |||
1646 | static struct pci_ops null_pci_ops = | ||
1647 | { | ||
1648 | .read = null_read_config, | ||
1649 | .write = null_write_config, | ||
1650 | }; | ||
1651 | |||
1652 | /* | ||
1653 | * These functions are used early on before PCI scanning is done | ||
1654 | * and all of the pci_dev and pci_bus structures have been created. | ||
1655 | */ | ||
1656 | static struct pci_bus * | ||
1657 | fake_pci_bus(struct pci_controller *hose, int busnr) | ||
1658 | { | ||
1659 | static struct pci_bus bus; | ||
1660 | |||
1661 | if (hose == 0) { | ||
1662 | printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr); | ||
1663 | } | ||
1664 | bus.number = busnr; | ||
1665 | bus.sysdata = hose; | ||
1666 | bus.ops = hose? hose->ops: &null_pci_ops; | ||
1667 | return &bus; | ||
1668 | } | ||
1669 | |||
1670 | #define EARLY_PCI_OP(rw, size, type) \ | ||
1671 | int early_##rw##_config_##size(struct pci_controller *hose, int bus, \ | ||
1672 | int devfn, int offset, type value) \ | ||
1673 | { \ | ||
1674 | return pci_bus_##rw##_config_##size(fake_pci_bus(hose, bus), \ | ||
1675 | devfn, offset, value); \ | ||
1676 | } | ||
1677 | |||
1678 | EARLY_PCI_OP(read, byte, u8 *) | ||
1679 | EARLY_PCI_OP(read, word, u16 *) | ||
1680 | EARLY_PCI_OP(read, dword, u32 *) | ||
1681 | EARLY_PCI_OP(write, byte, u8) | ||
1682 | EARLY_PCI_OP(write, word, u16) | ||
1683 | EARLY_PCI_OP(write, dword, u32) | ||
1684 | |||
1685 | extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap); | ||
1686 | int early_find_capability(struct pci_controller *hose, int bus, int devfn, | ||
1687 | int cap) | ||
1688 | { | ||
1689 | return pci_bus_find_capability(fake_pci_bus(hose, bus), devfn, cap); | ||
1690 | } | ||
1691 | |||
1692 | /** | ||
1693 | * pci_scan_phb - Given a pci_controller, setup and scan the PCI bus | ||
1694 | * @hose: Pointer to the PCI host controller instance structure | ||
1695 | * @sysdata: value to use for sysdata pointer. ppc32 and ppc64 differ here | ||
1696 | * | ||
1697 | * Note: the 'data' pointer is a temporary measure. As 32 and 64 bit | ||
1698 | * pci code gets merged, this parameter should become unnecessary because | ||
1699 | * both will use the same value. | ||
1700 | */ | ||
1701 | void __devinit pcibios_scan_phb(struct pci_controller *hose, void *sysdata) | ||
1702 | { | ||
1703 | struct pci_bus *bus; | ||
1704 | struct device_node *node = hose->dn; | ||
1705 | int mode; | ||
1706 | |||
1707 | pr_debug("PCI: Scanning PHB %s\n", | ||
1708 | node ? node->full_name : "<NO NAME>"); | ||
1709 | |||
1710 | /* Create an empty bus for the toplevel */ | ||
1711 | bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, | ||
1712 | sysdata); | ||
1713 | if (bus == NULL) { | ||
1714 | pr_err("Failed to create bus for PCI domain %04x\n", | ||
1715 | hose->global_number); | ||
1716 | return; | ||
1717 | } | ||
1718 | bus->secondary = hose->first_busno; | ||
1719 | hose->bus = bus; | ||
1720 | |||
1721 | /* Get some IO space for the new PHB */ | ||
1722 | pcibios_setup_phb_io_space(hose); | ||
1723 | |||
1724 | /* Wire up PHB bus resources */ | ||
1725 | pcibios_setup_phb_resources(hose); | ||
1726 | |||
1727 | /* Get probe mode and perform scan */ | ||
1728 | mode = PCI_PROBE_NORMAL; | ||
1729 | if (node && ppc_md.pci_probe_mode) | ||
1730 | mode = ppc_md.pci_probe_mode(bus); | ||
1731 | pr_debug(" probe mode: %d\n", mode); | ||
1732 | if (mode == PCI_PROBE_DEVTREE) { | ||
1733 | bus->subordinate = hose->last_busno; | ||
1734 | of_scan_bus(node, bus); | ||
1735 | } | ||
1736 | |||
1737 | if (mode == PCI_PROBE_NORMAL) | ||
1738 | hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); | ||
1739 | } | ||