diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2008-07-21 00:55:14 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2008-07-21 00:55:14 -0400 |
commit | 908cf4b925e419bc74f3297b2f0e51d6f8a81da2 (patch) | |
tree | 6c2da79366d4695a9c2560ab18259eca8a2a25b4 /drivers/ssb | |
parent | 92c49890922d54cba4b1eadeb0b185773c2c9570 (diff) | |
parent | 14b395e35d1afdd8019d11b92e28041fad591b71 (diff) | |
download | blackbird-obmc-linux-908cf4b925e419bc74f3297b2f0e51d6f8a81da2.tar.gz blackbird-obmc-linux-908cf4b925e419bc74f3297b2f0e51d6f8a81da2.zip |
Merge master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 into next
Diffstat (limited to 'drivers/ssb')
-rw-r--r-- | drivers/ssb/Kconfig | 2 | ||||
-rw-r--r-- | drivers/ssb/driver_pcicore.c | 9 | ||||
-rw-r--r-- | drivers/ssb/main.c | 77 | ||||
-rw-r--r-- | drivers/ssb/pci.c | 20 |
4 files changed, 81 insertions, 27 deletions
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig index cd845b8acd17..307b1f62d949 100644 --- a/drivers/ssb/Kconfig +++ b/drivers/ssb/Kconfig @@ -2,7 +2,7 @@ menu "Sonics Silicon Backplane" config SSB_POSSIBLE bool - depends on HAS_IOMEM + depends on HAS_IOMEM && HAS_DMA default y config SSB diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 75def13e797d..538c570df337 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c @@ -537,12 +537,19 @@ int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc, int err = 0; u32 tmp; - might_sleep(); + if (dev->bus->bustype != SSB_BUSTYPE_PCI) { + /* This SSB device is not on a PCI host-bus. So the IRQs are + * not routed through the PCI core. + * So we must not enable routing through the PCI core. */ + goto out; + } if (!pdev) goto out; bus = pdev->bus; + might_sleep_if(pdev->id.coreid != SSB_DEV_PCI); + /* Enable interrupts for this device. */ if (bus->host_pci && ((pdev->id.revision >= 6) || (pdev->id.coreid == SSB_DEV_PCIE))) { diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 7cf8851286b5..d831a2beff39 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -462,18 +462,15 @@ static int ssb_devices_register(struct ssb_bus *bus) #ifdef CONFIG_SSB_PCIHOST sdev->irq = bus->host_pci->irq; dev->parent = &bus->host_pci->dev; - sdev->dma_dev = &bus->host_pci->dev; #endif break; case SSB_BUSTYPE_PCMCIA: #ifdef CONFIG_SSB_PCMCIAHOST sdev->irq = bus->host_pcmcia->irq.AssignedIRQ; dev->parent = &bus->host_pcmcia->dev; - sdev->dma_dev = &bus->host_pcmcia->dev; #endif break; case SSB_BUSTYPE_SSB: - sdev->dma_dev = dev; break; } @@ -1156,30 +1153,82 @@ u32 ssb_dma_translation(struct ssb_device *dev) { switch (dev->bus->bustype) { case SSB_BUSTYPE_SSB: - case SSB_BUSTYPE_PCMCIA: return 0; case SSB_BUSTYPE_PCI: return SSB_PCI_DMA; + default: + __ssb_dma_not_implemented(dev); } return 0; } EXPORT_SYMBOL(ssb_dma_translation); -int ssb_dma_set_mask(struct ssb_device *ssb_dev, u64 mask) +int ssb_dma_set_mask(struct ssb_device *dev, u64 mask) { - struct device *dma_dev = ssb_dev->dma_dev; - -#ifdef CONFIG_SSB_PCIHOST - if (ssb_dev->bus->bustype == SSB_BUSTYPE_PCI) - return dma_set_mask(dma_dev, mask); -#endif - dma_dev->coherent_dma_mask = mask; - dma_dev->dma_mask = &dma_dev->coherent_dma_mask; + int err; - return 0; + switch (dev->bus->bustype) { + case SSB_BUSTYPE_PCI: + err = pci_set_dma_mask(dev->bus->host_pci, mask); + if (err) + return err; + err = pci_set_consistent_dma_mask(dev->bus->host_pci, mask); + return err; + case SSB_BUSTYPE_SSB: + return dma_set_mask(dev->dev, mask); + default: + __ssb_dma_not_implemented(dev); + } + return -ENOSYS; } EXPORT_SYMBOL(ssb_dma_set_mask); +void * ssb_dma_alloc_consistent(struct ssb_device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp_flags) +{ + switch (dev->bus->bustype) { + case SSB_BUSTYPE_PCI: + if (gfp_flags & GFP_DMA) { + /* Workaround: The PCI API does not support passing + * a GFP flag. */ + return dma_alloc_coherent(&dev->bus->host_pci->dev, + size, dma_handle, gfp_flags); + } + return pci_alloc_consistent(dev->bus->host_pci, size, dma_handle); + case SSB_BUSTYPE_SSB: + return dma_alloc_coherent(dev->dev, size, dma_handle, gfp_flags); + default: + __ssb_dma_not_implemented(dev); + } + return NULL; +} +EXPORT_SYMBOL(ssb_dma_alloc_consistent); + +void ssb_dma_free_consistent(struct ssb_device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle, + gfp_t gfp_flags) +{ + switch (dev->bus->bustype) { + case SSB_BUSTYPE_PCI: + if (gfp_flags & GFP_DMA) { + /* Workaround: The PCI API does not support passing + * a GFP flag. */ + dma_free_coherent(&dev->bus->host_pci->dev, + size, vaddr, dma_handle); + return; + } + pci_free_consistent(dev->bus->host_pci, size, + vaddr, dma_handle); + return; + case SSB_BUSTYPE_SSB: + dma_free_coherent(dev->dev, size, vaddr, dma_handle); + return; + default: + __ssb_dma_not_implemented(dev); + } +} +EXPORT_SYMBOL(ssb_dma_free_consistent); + int ssb_bus_may_powerdown(struct ssb_bus *bus) { struct ssb_chipcommon *cc; diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 57c4ccfab1ee..f883dcfffe06 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -510,17 +510,15 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, sprom_do_read(bus, buf); err = sprom_check_crc(buf, bus->sprom_size); if (err) { - /* check for rev 4 sprom - has special signature */ - if (buf[32] == 0x5372) { - kfree(buf); - buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), - GFP_KERNEL); - if (!buf) - goto out; - bus->sprom_size = SSB_SPROMSIZE_WORDS_R4; - sprom_do_read(bus, buf); - err = sprom_check_crc(buf, bus->sprom_size); - } + /* try for a 440 byte SPROM - revision 4 and higher */ + kfree(buf); + buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), + GFP_KERNEL); + if (!buf) + goto out; + bus->sprom_size = SSB_SPROMSIZE_WORDS_R4; + sprom_do_read(bus, buf); + err = sprom_check_crc(buf, bus->sprom_size); if (err) ssb_printk(KERN_WARNING PFX "WARNING: Invalid" " SPROM CRC (corrupt SPROM)\n"); |