aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb/main.c
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-06-20 05:50:29 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-27 09:09:15 -0400
commitf225763a7d6c92c4932dbd528437997078496fcc (patch)
tree5d787c7c0bdabcf72e98603a85672ebe95a3682e /drivers/ssb/main.c
parent316af76f3475bb73dbb11f1c6d549ae589efb3d0 (diff)
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: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/ssb/main.c')
-rw-r--r--drivers/ssb/main.c75
1 files changed, 59 insertions, 16 deletions
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index d184f2aea78d..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)
462#ifdef CONFIG_SSB_PCIHOST 462#ifdef CONFIG_SSB_PCIHOST
463 sdev->irq = bus->host_pci->irq; 463 sdev->irq = bus->host_pci->irq;
464 dev->parent = &bus->host_pci->dev; 464 dev->parent = &bus->host_pci->dev;
465 sdev->dma_dev = &bus->host_pci->dev;
466#endif 465#endif
467 break; 466 break;
468 case SSB_BUSTYPE_PCMCIA: 467 case SSB_BUSTYPE_PCMCIA:
469#ifdef CONFIG_SSB_PCMCIAHOST 468#ifdef CONFIG_SSB_PCMCIAHOST
470 sdev->irq = bus->host_pcmcia->irq.AssignedIRQ; 469 sdev->irq = bus->host_pcmcia->irq.AssignedIRQ;
471 dev->parent = &bus->host_pcmcia->dev; 470 dev->parent = &bus->host_pcmcia->dev;
472 sdev->dma_dev = &bus->host_pcmcia->dev;
473#endif 471#endif
474 break; 472 break;
475 case SSB_BUSTYPE_SSB: 473 case SSB_BUSTYPE_SSB:
476 sdev->dma_dev = dev;
477 break; 474 break;
478 } 475 }
479 476
@@ -1156,36 +1153,82 @@ u32 ssb_dma_translation(struct ssb_device *dev)
1156{ 1153{
1157 switch (dev->bus->bustype) { 1154 switch (dev->bus->bustype) {
1158 case SSB_BUSTYPE_SSB: 1155 case SSB_BUSTYPE_SSB:
1159 case SSB_BUSTYPE_PCMCIA:
1160 return 0; 1156 return 0;
1161 case SSB_BUSTYPE_PCI: 1157 case SSB_BUSTYPE_PCI:
1162 return SSB_PCI_DMA; 1158 return SSB_PCI_DMA;
1159 default:
1160 __ssb_dma_not_implemented(dev);
1163 } 1161 }
1164 return 0; 1162 return 0;
1165} 1163}
1166EXPORT_SYMBOL(ssb_dma_translation); 1164EXPORT_SYMBOL(ssb_dma_translation);
1167 1165
1168int ssb_dma_set_mask(struct ssb_device *ssb_dev, u64 mask) 1166int ssb_dma_set_mask(struct ssb_device *dev, u64 mask)
1169{ 1167{
1170 struct device *dma_dev = ssb_dev->dma_dev; 1168 int err;
1171 int err = 0;
1172 1169
1173#ifdef CONFIG_SSB_PCIHOST 1170 switch (dev->bus->bustype) {
1174 if (ssb_dev->bus->bustype == SSB_BUSTYPE_PCI) { 1171 case SSB_BUSTYPE_PCI:
1175 err = pci_set_dma_mask(ssb_dev->bus->host_pci, mask); 1172 err = pci_set_dma_mask(dev->bus->host_pci, mask);
1176 if (err) 1173 if (err)
1177 return err; 1174 return err;
1178 err = pci_set_consistent_dma_mask(ssb_dev->bus->host_pci, mask); 1175 err = pci_set_consistent_dma_mask(dev->bus->host_pci, mask);
1179 return err; 1176 return err;
1177 case SSB_BUSTYPE_SSB:
1178 return dma_set_mask(dev->dev, mask);
1179 default:
1180 __ssb_dma_not_implemented(dev);
1180 } 1181 }
1181#endif 1182 return -ENOSYS;
1182 dma_dev->coherent_dma_mask = mask;
1183 dma_dev->dma_mask = &dma_dev->coherent_dma_mask;
1184
1185 return err;
1186} 1183}
1187EXPORT_SYMBOL(ssb_dma_set_mask); 1184EXPORT_SYMBOL(ssb_dma_set_mask);
1188 1185
1186void * ssb_dma_alloc_consistent(struct ssb_device *dev, size_t size,
1187 dma_addr_t *dma_handle, gfp_t gfp_flags)
1188{
1189 switch (dev->bus->bustype) {
1190 case SSB_BUSTYPE_PCI:
1191 if (gfp_flags & GFP_DMA) {
1192 /* Workaround: The PCI API does not support passing
1193 * a GFP flag. */
1194 return dma_alloc_coherent(&dev->bus->host_pci->dev,
1195 size, dma_handle, gfp_flags);
1196 }
1197 return pci_alloc_consistent(dev->bus->host_pci, size, dma_handle);
1198 case SSB_BUSTYPE_SSB:
1199 return dma_alloc_coherent(dev->dev, size, dma_handle, gfp_flags);
1200 default:
1201 __ssb_dma_not_implemented(dev);
1202 }
1203 return NULL;
1204}
1205EXPORT_SYMBOL(ssb_dma_alloc_consistent);
1206
1207void ssb_dma_free_consistent(struct ssb_device *dev, size_t size,
1208 void *vaddr, dma_addr_t dma_handle,
1209 gfp_t gfp_flags)
1210{
1211 switch (dev->bus->bustype) {
1212 case SSB_BUSTYPE_PCI:
1213 if (gfp_flags & GFP_DMA) {
1214 /* Workaround: The PCI API does not support passing
1215 * a GFP flag. */
1216 dma_free_coherent(&dev->bus->host_pci->dev,
1217 size, vaddr, dma_handle);
1218 return;
1219 }
1220 pci_free_consistent(dev->bus->host_pci, size,
1221 vaddr, dma_handle);
1222 return;
1223 case SSB_BUSTYPE_SSB:
1224 dma_free_coherent(dev->dev, size, vaddr, dma_handle);
1225 return;
1226 default:
1227 __ssb_dma_not_implemented(dev);
1228 }
1229}
1230EXPORT_SYMBOL(ssb_dma_free_consistent);
1231
1189int ssb_bus_may_powerdown(struct ssb_bus *bus) 1232int ssb_bus_may_powerdown(struct ssb_bus *bus)
1190{ 1233{
1191 struct ssb_chipcommon *cc; 1234 struct ssb_chipcommon *cc;