Skip to content

Commit

Permalink
PCI/cardbus: Add a fixup hook and fix powerpc
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Benjamin Herrenschmidt authored and Jesse Barnes committed Dec 17, 2009
1 parent 7e8af37 commit 2d1c861
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 1 deletion.
13 changes: 13 additions & 0 deletions arch/powerpc/kernel/pci-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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) &&
Expand Down
5 changes: 5 additions & 0 deletions drivers/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -2798,6 +2798,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) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/pcmcia/cardbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,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++)
Expand Down
3 changes: 3 additions & 0 deletions include/linux/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,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);
Expand Down

0 comments on commit 2d1c861

Please sign in to comment.