aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2010-01-19 12:42:19 +0100
committerGreg Kroah-Hartman <gregkh@suse.de>2010-01-22 15:18:26 -0800
commit2db740cb364a38b6bf50e1c61dc6d9615bfe390c (patch)
tree070ab3b6c8ab6855268e6e873b54d965741fd74e
parenteecd8a9ec6488e6b5c43c1c12368d6fdb8aa9430 (diff)
PCI/cardbus: Add a fixup hook and fix powerpc
commit 2d1c861871d767153538a77c498752b36d4bb4b8 upstream The cardbus code creates PCI devices without ever going through the necessary fixup bits and pieces that normal PCI devices go through. There's in fact a commented out call to pcibios_fixup_bus() in there, it's commented because ... it doesn't work. I could make pcibios_fixup_bus() do the right thing on powerpc easily but I felt it cleaner instead to provide a specific hook pci_fixup_cardbus for which a weak empty implementation is provided by the PCI core. This fixes cardbus on powerbooks and probably all other PowerPC platforms which was broken completely for ever on some platforms and since 2.6.31 on others such as PowerBooks when we made the DMA ops mandatory (since those are setup by the fixups). Acked-by: Dominik Brodowski <linux@dominikbrodowski.net> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Stefan Bader <stefan.bader@canonical.com> Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--arch/powerpc/kernel/pci-common.c13
-rw-r--r--drivers/pci/pci.c5
-rw-r--r--drivers/pcmcia/cardbus.c2
-rw-r--r--include/linux/pci.h3
4 files changed, 22 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index e8dfdbd9327a..cadbed679fbb 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1107,6 +1107,12 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
list_for_each_entry(dev, &bus->devices, bus_list) {
struct dev_archdata *sd = &dev->dev.archdata;
+ /* Cardbus can call us to add new devices to a bus, so ignore
+ * those who are already fully discovered
+ */
+ if (dev->is_added)
+ continue;
+
/* Setup OF node pointer in archdata */
sd->of_node = pci_device_to_OF_node(dev);
@@ -1147,6 +1153,13 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
}
EXPORT_SYMBOL(pcibios_fixup_bus);
+void __devinit pci_fixup_cardbus(struct pci_bus *bus)
+{
+ /* Now fixup devices on that bus */
+ pcibios_setup_bus_devices(bus);
+}
+
+
static int skip_isa_ioresource_align(struct pci_dev *dev)
{
if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) &&
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 4e4c295a049f..64777220a719 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2723,6 +2723,11 @@ int __attribute__ ((weak)) pci_ext_cfg_avail(struct pci_dev *dev)
return 1;
}
+void __weak pci_fixup_cardbus(struct pci_bus *bus)
+{
+}
+EXPORT_SYMBOL(pci_fixup_cardbus);
+
static int __init pci_setup(char *str)
{
while (str) {
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index db77e1f3309a..5c2679355b72 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -214,7 +214,7 @@ int __ref cb_alloc(struct pcmcia_socket * s)
unsigned int max, pass;
s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0));
-// pcibios_fixup_bus(bus);
+ pci_fixup_cardbus(bus);
max = bus->secondary;
for (pass = 0; pass < 2; pass++)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index f5c7cd343e56..2547515f7e92 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -564,6 +564,9 @@ void pcibios_align_resource(void *, struct resource *, resource_size_t,
resource_size_t);
void pcibios_update_irq(struct pci_dev *, int irq);
+/* Weak but can be overriden by arch */
+void pci_fixup_cardbus(struct pci_bus *);
+
/* Generic PCI functions used internally */
extern struct pci_bus *pci_find_bus(int domain, int busnr);