Commit f225763a authored by Michael Buesch's avatar Michael Buesch Committed by John W. Linville

ssb, b43, b43legacy, b44: Rewrite SSB DMA API

This is a rewrite of the DMA API for SSB devices.
This is needed, because the old (non-existing) "API" made too many bad
assumptions on the API of the host-bus (PCI).
This introduces an almost complete SSB-DMA-API that maps to the lowlevel
bus-API based on the bustype.
Signed-off-by: default avatarMichael Buesch <mb@bu3sch.de>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 316af76f
This diff is collapsed.
...@@ -328,11 +328,11 @@ static inline ...@@ -328,11 +328,11 @@ static inline
dma_addr_t dmaaddr; dma_addr_t dmaaddr;
if (tx) { if (tx) {
dmaaddr = dma_map_single(ring->dev->dev->dma_dev, dmaaddr = ssb_dma_map_single(ring->dev->dev,
buf, len, DMA_TO_DEVICE); buf, len, DMA_TO_DEVICE);
} else { } else {
dmaaddr = dma_map_single(ring->dev->dev->dma_dev, dmaaddr = ssb_dma_map_single(ring->dev->dev,
buf, len, DMA_FROM_DEVICE); buf, len, DMA_FROM_DEVICE);
} }
return dmaaddr; return dmaaddr;
...@@ -343,11 +343,11 @@ static inline ...@@ -343,11 +343,11 @@ static inline
dma_addr_t addr, size_t len, int tx) dma_addr_t addr, size_t len, int tx)
{ {
if (tx) { if (tx) {
dma_unmap_single(ring->dev->dev->dma_dev, ssb_dma_unmap_single(ring->dev->dev,
addr, len, DMA_TO_DEVICE); addr, len, DMA_TO_DEVICE);
} else { } else {
dma_unmap_single(ring->dev->dev->dma_dev, ssb_dma_unmap_single(ring->dev->dev,
addr, len, DMA_FROM_DEVICE); addr, len, DMA_FROM_DEVICE);
} }
} }
...@@ -356,8 +356,8 @@ static inline ...@@ -356,8 +356,8 @@ static inline
dma_addr_t addr, size_t len) dma_addr_t addr, size_t len)
{ {
B43_WARN_ON(ring->tx); B43_WARN_ON(ring->tx);
dma_sync_single_for_cpu(ring->dev->dev->dma_dev, ssb_dma_sync_single_for_cpu(ring->dev->dev,
addr, len, DMA_FROM_DEVICE); addr, len, DMA_FROM_DEVICE);
} }
static inline static inline
...@@ -365,8 +365,8 @@ static inline ...@@ -365,8 +365,8 @@ static inline
dma_addr_t addr, size_t len) dma_addr_t addr, size_t len)
{ {
B43_WARN_ON(ring->tx); B43_WARN_ON(ring->tx);
dma_sync_single_for_device(ring->dev->dev->dma_dev, ssb_dma_sync_single_for_device(ring->dev->dev,
addr, len, DMA_FROM_DEVICE); addr, len, DMA_FROM_DEVICE);
} }
static inline static inline
...@@ -381,7 +381,6 @@ static inline ...@@ -381,7 +381,6 @@ static inline
static int alloc_ringmemory(struct b43_dmaring *ring) static int alloc_ringmemory(struct b43_dmaring *ring)
{ {
struct device *dma_dev = ring->dev->dev->dma_dev;
gfp_t flags = GFP_KERNEL; gfp_t flags = GFP_KERNEL;
/* The specs call for 4K buffers for 30- and 32-bit DMA with 4K /* The specs call for 4K buffers for 30- and 32-bit DMA with 4K
...@@ -392,11 +391,14 @@ static int alloc_ringmemory(struct b43_dmaring *ring) ...@@ -392,11 +391,14 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
* For unknown reasons - possibly a hardware error - the BCM4311 rev * For unknown reasons - possibly a hardware error - the BCM4311 rev
* 02, which uses 64-bit DMA, needs the ring buffer in very low memory, * 02, which uses 64-bit DMA, needs the ring buffer in very low memory,
* which accounts for the GFP_DMA flag below. * which accounts for the GFP_DMA flag below.
*
* The flags here must match the flags in free_ringmemory below!
*/ */
if (ring->type == B43_DMA_64BIT) if (ring->type == B43_DMA_64BIT)
flags |= GFP_DMA; flags |= GFP_DMA;
ring->descbase = dma_alloc_coherent(dma_dev, B43_DMA_RINGMEMSIZE, ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev,
&(ring->dmabase), flags); B43_DMA_RINGMEMSIZE,
&(ring->dmabase), flags);
if (!ring->descbase) { if (!ring->descbase) {
b43err(ring->dev->wl, "DMA ringmemory allocation failed\n"); b43err(ring->dev->wl, "DMA ringmemory allocation failed\n");
return -ENOMEM; return -ENOMEM;
...@@ -408,10 +410,13 @@ static int alloc_ringmemory(struct b43_dmaring *ring) ...@@ -408,10 +410,13 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
static void free_ringmemory(struct b43_dmaring *ring) static void free_ringmemory(struct b43_dmaring *ring)
{ {
struct device *dma_dev = ring->dev->dev->dma_dev; gfp_t flags = GFP_KERNEL;
if (ring->type == B43_DMA_64BIT)
flags |= GFP_DMA;
dma_free_coherent(dma_dev, B43_DMA_RINGMEMSIZE, ssb_dma_free_consistent(ring->dev->dev, B43_DMA_RINGMEMSIZE,
ring->descbase, ring->dmabase); ring->descbase, ring->dmabase, flags);
} }
/* Reset the RX DMA channel */ /* Reset the RX DMA channel */
...@@ -518,7 +523,7 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, ...@@ -518,7 +523,7 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring,
dma_addr_t addr, dma_addr_t addr,
size_t buffersize, bool dma_to_device) size_t buffersize, bool dma_to_device)
{ {
if (unlikely(dma_mapping_error(addr))) if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr)))
return 1; return 1;
switch (ring->type) { switch (ring->type) {
...@@ -844,10 +849,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, ...@@ -844,10 +849,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
goto err_kfree_meta; goto err_kfree_meta;
/* test for ability to dma to txhdr_cache */ /* test for ability to dma to txhdr_cache */
dma_test = dma_map_single(dev->dev->dma_dev, dma_test = ssb_dma_map_single(dev->dev,
ring->txhdr_cache, ring->txhdr_cache,
b43_txhdr_size(dev), b43_txhdr_size(dev),
DMA_TO_DEVICE); DMA_TO_DEVICE);
if (b43_dma_mapping_error(ring, dma_test, if (b43_dma_mapping_error(ring, dma_test,
b43_txhdr_size(dev), 1)) { b43_txhdr_size(dev), 1)) {
...@@ -859,10 +864,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, ...@@ -859,10 +864,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
if (!ring->txhdr_cache) if (!ring->txhdr_cache)
goto err_kfree_meta; goto err_kfree_meta;
dma_test = dma_map_single(dev->dev->dma_dev, dma_test = ssb_dma_map_single(dev->dev,
ring->txhdr_cache, ring->txhdr_cache,
b43_txhdr_size(dev), b43_txhdr_size(dev),
DMA_TO_DEVICE); DMA_TO_DEVICE);
if (b43_dma_mapping_error(ring, dma_test, if (b43_dma_mapping_error(ring, dma_test,
b43_txhdr_size(dev), 1)) { b43_txhdr_size(dev), 1)) {
...@@ -873,9 +878,9 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, ...@@ -873,9 +878,9 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
} }
} }
dma_unmap_single(dev->dev->dma_dev, ssb_dma_unmap_single(dev->dev,
dma_test, b43_txhdr_size(dev), dma_test, b43_txhdr_size(dev),
DMA_TO_DEVICE); DMA_TO_DEVICE);
} }
err = alloc_ringmemory(ring); err = alloc_ringmemory(ring);
......
...@@ -393,13 +393,13 @@ dma_addr_t map_descbuffer(struct b43legacy_dmaring *ring, ...@@ -393,13 +393,13 @@ dma_addr_t map_descbuffer(struct b43legacy_dmaring *ring,
dma_addr_t dmaaddr; dma_addr_t dmaaddr;
if (tx) if (tx)
dmaaddr = dma_map_single(ring->dev->dev->dma_dev, dmaaddr = ssb_dma_map_single(ring->dev->dev,
buf, len, buf, len,
DMA_TO_DEVICE); DMA_TO_DEVICE);
else else
dmaaddr = dma_map_single(ring->dev->dev->dma_dev, dmaaddr = ssb_dma_map_single(ring->dev->dev,
buf, len, buf, len,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
return dmaaddr; return dmaaddr;
} }
...@@ -411,13 +411,13 @@ void unmap_descbuffer(struct b43legacy_dmaring *ring, ...@@ -411,13 +411,13 @@ void unmap_descbuffer(struct b43legacy_dmaring *ring,
int tx) int tx)
{ {
if (tx) if (tx)
dma_unmap_single(ring->dev->dev->dma_dev, ssb_dma_unmap_single(ring->dev->dev,
addr, len, addr, len,
DMA_TO_DEVICE); DMA_TO_DEVICE);
else else
dma_unmap_single(ring->dev->dev->dma_dev, ssb_dma_unmap_single(ring->dev->dev,
addr, len, addr, len,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
} }
static inline static inline
...@@ -427,8 +427,8 @@ void sync_descbuffer_for_cpu(struct b43legacy_dmaring *ring, ...@@ -427,8 +427,8 @@ void sync_descbuffer_for_cpu(struct b43legacy_dmaring *ring,
{ {
B43legacy_WARN_ON(ring->tx); B43legacy_WARN_ON(ring->tx);
dma_sync_single_for_cpu(ring->dev->dev->dma_dev, ssb_dma_sync_single_for_cpu(ring->dev->dev,
addr, len, DMA_FROM_DEVICE); addr, len, DMA_FROM_DEVICE);
} }
static inline static inline
...@@ -438,8 +438,8 @@ void sync_descbuffer_for_device(struct b43legacy_dmaring *ring, ...@@ -438,8 +438,8 @@ void sync_descbuffer_for_device(struct b43legacy_dmaring *ring,
{ {
B43legacy_WARN_ON(ring->tx); B43legacy_WARN_ON(ring->tx);
dma_sync_single_for_device(ring->dev->dev->dma_dev, ssb_dma_sync_single_for_device(ring->dev->dev,
addr, len, DMA_FROM_DEVICE); addr, len, DMA_FROM_DEVICE);
} }
static inline static inline
...@@ -458,10 +458,11 @@ void free_descriptor_buffer(struct b43legacy_dmaring *ring, ...@@ -458,10 +458,11 @@ void free_descriptor_buffer(struct b43legacy_dmaring *ring,
static int alloc_ringmemory(struct b43legacy_dmaring *ring) static int alloc_ringmemory(struct b43legacy_dmaring *ring)
{ {
struct device *dma_dev = ring->dev->dev->dma_dev; /* GFP flags must match the flags in free_ringmemory()! */
ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev,
ring->descbase = dma_alloc_coherent(dma_dev, B43legacy_DMA_RINGMEMSIZE, B43legacy_DMA_RINGMEMSIZE,
&(ring->dmabase), GFP_KERNEL); &(ring->dmabase),
GFP_KERNEL);
if (!ring->descbase) { if (!ring->descbase) {
b43legacyerr(ring->dev->wl, "DMA ringmemory allocation" b43legacyerr(ring->dev->wl, "DMA ringmemory allocation"
" failed\n"); " failed\n");
...@@ -474,10 +475,8 @@ static int alloc_ringmemory(struct b43legacy_dmaring *ring) ...@@ -474,10 +475,8 @@ static int alloc_ringmemory(struct b43legacy_dmaring *ring)
static void free_ringmemory(struct b43legacy_dmaring *ring) static void free_ringmemory(struct b43legacy_dmaring *ring)
{ {
struct device *dma_dev = ring->dev->dev->dma_dev; ssb_dma_free_consistent(ring->dev->dev, B43legacy_DMA_RINGMEMSIZE,
ring->descbase, ring->dmabase, GFP_KERNEL);
dma_free_coherent(dma_dev, B43legacy_DMA_RINGMEMSIZE,
ring->descbase, ring->dmabase);
} }
/* Reset the RX DMA channel */ /* Reset the RX DMA channel */
...@@ -589,7 +588,7 @@ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring, ...@@ -589,7 +588,7 @@ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring,
size_t buffersize, size_t buffersize,
bool dma_to_device) bool dma_to_device)
{ {
if (unlikely(dma_mapping_error(addr))) if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr)))
return 1; return 1;
switch (ring->type) { switch (ring->type) {
...@@ -893,9 +892,9 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, ...@@ -893,9 +892,9 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
goto err_kfree_meta; goto err_kfree_meta;
/* test for ability to dma to txhdr_cache */ /* test for ability to dma to txhdr_cache */
dma_test = dma_map_single(dev->dev->dma_dev, ring->txhdr_cache, dma_test = ssb_dma_map_single(dev->dev, ring->txhdr_cache,
sizeof(struct b43legacy_txhdr_fw3), sizeof(struct b43legacy_txhdr_fw3),
DMA_TO_DEVICE); DMA_TO_DEVICE);
if (b43legacy_dma_mapping_error(ring, dma_test, if (b43legacy_dma_mapping_error(ring, dma_test,
sizeof(struct b43legacy_txhdr_fw3), 1)) { sizeof(struct b43legacy_txhdr_fw3), 1)) {
...@@ -907,7 +906,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, ...@@ -907,7 +906,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
if (!ring->txhdr_cache) if (!ring->txhdr_cache)
goto err_kfree_meta; goto err_kfree_meta;
dma_test = dma_map_single(dev->dev->dma_dev, dma_test = ssb_dma_map_single(dev->dev,
ring->txhdr_cache, ring->txhdr_cache,
sizeof(struct b43legacy_txhdr_fw3), sizeof(struct b43legacy_txhdr_fw3),
DMA_TO_DEVICE); DMA_TO_DEVICE);
...@@ -917,9 +916,9 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, ...@@ -917,9 +916,9 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
goto err_kfree_txhdr_cache; goto err_kfree_txhdr_cache;
} }
dma_unmap_single(dev->dev->dma_dev, ssb_dma_unmap_single(dev->dev, dma_test,
dma_test, sizeof(struct b43legacy_txhdr_fw3), sizeof(struct b43legacy_txhdr_fw3),
DMA_TO_DEVICE); DMA_TO_DEVICE);
} }
ring->dev = dev; ring->dev = dev;
......
...@@ -2,7 +2,7 @@ menu "Sonics Silicon Backplane" ...@@ -2,7 +2,7 @@ menu "Sonics Silicon Backplane"
config SSB_POSSIBLE config SSB_POSSIBLE
bool bool
depends on HAS_IOMEM depends on HAS_IOMEM && HAS_DMA
default y default y
config SSB config SSB
......
...@@ -462,18 +462,15 @@ static int ssb_devices_register(struct ssb_bus *bus) ...@@ -462,18 +462,15 @@ static int ssb_devices_register(struct ssb_bus *bus)
#ifdef CONFIG_SSB_PCIHOST #ifdef CONFIG_SSB_PCIHOST
sdev->irq = bus->host_pci->irq; sdev->irq = bus->host_pci->irq;
dev->parent = &bus->host_pci->dev; dev->parent = &bus->host_pci->dev;
sdev->dma_dev = &bus->host_pci->dev;
#endif #endif
break; break;
case SSB_BUSTYPE_PCMCIA: case SSB_BUSTYPE_PCMCIA:
#ifdef CONFIG_SSB_PCMCIAHOST #ifdef CONFIG_SSB_PCMCIAHOST
sdev->irq = bus->host_pcmcia->irq.AssignedIRQ; sdev->irq = bus->host_pcmcia->irq.AssignedIRQ;
dev->parent = &bus->host_pcmcia->dev; dev->parent = &bus->host_pcmcia->dev;
sdev->dma_dev = &bus->host_pcmcia->dev;
#endif #endif
break; break;
case SSB_BUSTYPE_SSB: case SSB_BUSTYPE_SSB:
sdev->dma_dev = dev;
break; break;
} }
...@@ -1156,36 +1153,82 @@ u32 ssb_dma_translation(struct ssb_device *dev) ...@@ -1156,36 +1153,82 @@ u32 ssb_dma_translation(struct ssb_device *dev)
{ {
switch (dev->bus->bustype) { switch (dev->bus->bustype) {
case SSB_BUSTYPE_SSB: case SSB_BUSTYPE_SSB:
case SSB_BUSTYPE_PCMCIA:
return 0; return 0;
case SSB_BUSTYPE_PCI: case SSB_BUSTYPE_PCI:
return SSB_PCI_DMA; return SSB_PCI_DMA;
default:
__ssb_dma_not_implemented(dev);
} }
return 0; return 0;
} }
EXPORT_SYMBOL(ssb_dma_translation); 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; int err;
int err = 0;
#ifdef CONFIG_SSB_PCIHOST switch (dev->bus->bustype) {
if (ssb_dev->bus->bustype == SSB_BUSTYPE_PCI) { case SSB_BUSTYPE_PCI:
err = pci_set_dma_mask(ssb_dev->bus->host_pci, mask); err = pci_set_dma_mask(dev->bus->host_pci, mask);
if (err) if (err)
return err; return err;
err = pci_set_consistent_dma_mask(ssb_dev->bus->host_pci, mask); err = pci_set_consistent_dma_mask(dev->bus->host_pci, mask);
return err; return err;
case SSB_BUSTYPE_SSB:
return dma_set_mask(dev->dev, mask);
default:
__ssb_dma_not_implemented(dev);
} }
#endif return -ENOSYS;
dma_dev->coherent_dma_mask = mask;
dma_dev->dma_mask = &dma_dev->coherent_dma_mask;
return err;
} }
EXPORT_SYMBOL(ssb_dma_set_mask); 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) int ssb_bus_may_powerdown(struct ssb_bus *bus)
{ {
struct ssb_chipcommon *cc; struct ssb_chipcommon *cc;
......
...@@ -137,9 +137,6 @@ struct ssb_device { ...@@ -137,9 +137,6 @@ struct ssb_device {
const struct ssb_bus_ops *ops; const struct ssb_bus_ops *ops;
struct device *dev; struct device *dev;
/* Pointer to the device that has to be used for
* any DMA related operation. */
struct device *dma_dev;
struct ssb_bus *bus; struct ssb_bus *bus;
struct ssb_device_id id; struct ssb_device_id id;
...@@ -399,13 +396,151 @@ static inline void ssb_block_write(struct ssb_device *dev, const void *buffer, ...@@ -399,13 +396,151 @@ static inline void ssb_block_write(struct ssb_device *dev, const void *buffer,
#endif /* CONFIG_SSB_BLOCKIO */ #endif /* CONFIG_SSB_BLOCKIO */
/* The SSB DMA API. Use this API for any DMA operation on the device.
* This API basically is a wrapper that calls the correct DMA API for
* the host device type the SSB device is attached to. */
/* Translation (routing) bits that need to be ORed to DMA /* Translation (routing) bits that need to be ORed to DMA
* addresses before they are given to a device. */ * addresses before they are given to a device. */
extern u32 ssb_dma_translation(struct ssb_device *dev); extern u32 ssb_dma_translation(struct ssb_device *dev);
#define SSB_DMA_TRANSLATION_MASK 0xC0000000 #define SSB_DMA_TRANSLATION_MASK 0xC0000000
#define SSB_DMA_TRANSLATION_SHIFT 30 #define SSB_DMA_TRANSLATION_SHIFT 30
extern int ssb_dma_set_mask(struct ssb_device *ssb_dev, u64 mask); extern int ssb_dma_set_mask(struct ssb_device *dev, u64 mask);
extern void * ssb_dma_alloc_consistent(struct ssb_device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp_flags);
extern void ssb_dma_free_consistent(struct ssb_device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle,
gfp_t gfp_flags);
static inline void __cold __ssb_dma_not_implemented(struct ssb_device *dev)
{
#ifdef CONFIG_SSB_DEBUG
printk(KERN_ERR "SSB: BUG! Calling DMA API for "
"unsupported bustype %d\n", dev->bus->bustype);
#endif /* DEBUG */
}
static inline int ssb_dma_mapping_error(struct ssb_device *dev, dma_addr_t addr)
{
switch (dev->bus->bustype) {
case SSB_BUSTYPE_PCI:
return pci_dma_mapping_error(addr);
case SSB_BUSTYPE_SSB:
return dma_mapping_error(addr);
default:
__ssb_dma_not_implemented(dev);
}
return -ENOSYS;
}
static inline dma_addr_t ssb_dma_map_single(struct ssb_device *dev, void *p,
size_t size, enum dma_data_direction dir)
{
switch (dev->bus->bustype) {
case SSB_BUSTYPE_PCI:
return pci_map_single(dev->bus->host_pci, p, size, dir);
case SSB_BUSTYPE_SSB:
return dma_map_single(dev->dev, p, size, dir);
default:
__ssb_dma_not_implemented(dev);
}
return 0;
}
static inline void ssb_dma_unmap_single(struct ssb_device *dev, dma_addr_t dma_addr,
size_t size, enum dma_data_direction dir)
{
switch (dev->bus->bustype) {
case SSB_BUSTYPE_PCI:
pci_unmap_single(dev->bus->host_pci, dma_addr, size, dir);
return;
case SSB_BUSTYPE_SSB:
dma_unmap_single(dev->dev, dma_addr, size, dir);
return;
default:
__ssb_dma_not_implemented(dev);
}
}
static inline void ssb_dma_sync_single_for_cpu(struct ssb_device *dev,
dma_addr_t dma_addr,
size_t size,
enum dma_data_direction dir)
{
switch (dev->bus->bustype) {
case SSB_BUSTYPE_PCI:
pci_dma_sync_single_for_cpu(dev->bus->host_pci, dma_addr,
size, dir);
return;
case SSB_BUSTYPE_SSB:
dma_sync_single_for_cpu(dev->dev, dma_addr, size, dir);
return;
default:
__ssb_dma_not_implemented(dev);
}
}
static inline void ssb_dma_sync_single_for_device(struct ssb_device *dev,
dma_addr_t dma_addr,
size_t size,
enum dma_data_direction dir)
{
switch (dev->bus->bustype) {
case SSB_BUSTYPE_PCI:
pci_dma_sync_single_for_device(dev->bus->host_pci, dma_addr,
size, dir);
return;
case SSB_BUSTYPE_SSB:
dma_sync_single_for_device(dev->dev, dma_addr, size, dir);
return;
default:
__ssb_dma_not_implemented(dev);
}
}
static inline void ssb_dma_sync_single_range_for_cpu(struct ssb_device *dev,
dma_addr_t dma_addr,
unsigned long offset,
size_t size,
enum dma_data_direction dir)
{
switch (dev->bus->bustype) {
case SSB_BUSTYPE_PCI:
/* Just sync everything. That's all the PCI API can do. */
pci_dma_sync_single_for_cpu(dev->bus->host_pci, dma_addr,
offset + size, dir);
return;
case SSB_BUSTYPE_SSB:
dma_sync_single_range_for_cpu(dev->dev, dma_addr, offset,
size, dir);
return;
default:
__ssb_dma_not_implemented(dev);
}
}
static inline void ssb_dma_sync_single_range_for_device(struct ssb_device *dev,
dma_addr_t dma_addr,
unsigned long offset,
size_t size,
enum dma_data_direction dir)
{
switch (dev->bus->bustype) {
case SSB_BUSTYPE_PCI:
/* Just sync everything. That's all the PCI API can do. */
pci_dma_sync_single_for_device(dev->bus->host_pci, dma_addr,
offset + size, dir);
return;
case SSB_BUSTYPE_SSB:
dma_sync_single_range_for_device(dev->dev, dma_addr, offset,
size, dir);
return;
default:
__ssb_dma_not_implemented(dev);
}
}
#ifdef CONFIG_SSB_PCIHOST #ifdef CONFIG_SSB_PCIHOST
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment