diff options
Diffstat (limited to 'drivers/ssb')
-rw-r--r-- | drivers/ssb/driver_chipcommon.c | 25 | ||||
-rw-r--r-- | drivers/ssb/driver_chipcommon_pmu.c | 17 | ||||
-rw-r--r-- | drivers/ssb/main.c | 76 | ||||
-rw-r--r-- | drivers/ssb/pci.c | 15 |
4 files changed, 47 insertions, 86 deletions
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index 59ae76bace14..7c031fdc8205 100644 --- a/drivers/ssb/driver_chipcommon.c +++ b/drivers/ssb/driver_chipcommon.c | |||
@@ -209,6 +209,24 @@ static void chipco_powercontrol_init(struct ssb_chipcommon *cc) | |||
209 | } | 209 | } |
210 | } | 210 | } |
211 | 211 | ||
212 | /* http://bcm-v4.sipsolutions.net/802.11/PmuFastPwrupDelay */ | ||
213 | static u16 pmu_fast_powerup_delay(struct ssb_chipcommon *cc) | ||
214 | { | ||
215 | struct ssb_bus *bus = cc->dev->bus; | ||
216 | |||
217 | switch (bus->chip_id) { | ||
218 | case 0x4312: | ||
219 | case 0x4322: | ||
220 | case 0x4328: | ||
221 | return 7000; | ||
222 | case 0x4325: | ||
223 | /* TODO: */ | ||
224 | default: | ||
225 | return 15000; | ||
226 | } | ||
227 | } | ||
228 | |||
229 | /* http://bcm-v4.sipsolutions.net/802.11/ClkctlFastPwrupDelay */ | ||
212 | static void calc_fast_powerup_delay(struct ssb_chipcommon *cc) | 230 | static void calc_fast_powerup_delay(struct ssb_chipcommon *cc) |
213 | { | 231 | { |
214 | struct ssb_bus *bus = cc->dev->bus; | 232 | struct ssb_bus *bus = cc->dev->bus; |
@@ -218,6 +236,12 @@ static void calc_fast_powerup_delay(struct ssb_chipcommon *cc) | |||
218 | 236 | ||
219 | if (bus->bustype != SSB_BUSTYPE_PCI) | 237 | if (bus->bustype != SSB_BUSTYPE_PCI) |
220 | return; | 238 | return; |
239 | |||
240 | if (cc->capabilities & SSB_CHIPCO_CAP_PMU) { | ||
241 | cc->fast_pwrup_delay = pmu_fast_powerup_delay(cc); | ||
242 | return; | ||
243 | } | ||
244 | |||
221 | if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL)) | 245 | if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL)) |
222 | return; | 246 | return; |
223 | 247 | ||
@@ -235,6 +259,7 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc) | |||
235 | return; /* We don't have a ChipCommon */ | 259 | return; /* We don't have a ChipCommon */ |
236 | if (cc->dev->id.revision >= 11) | 260 | if (cc->dev->id.revision >= 11) |
237 | cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); | 261 | cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); |
262 | ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status); | ||
238 | ssb_pmu_init(cc); | 263 | ssb_pmu_init(cc); |
239 | chipco_powercontrol_init(cc); | 264 | chipco_powercontrol_init(cc); |
240 | ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); | 265 | ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); |
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c index 3d551245a4e2..5732bb2c3578 100644 --- a/drivers/ssb/driver_chipcommon_pmu.c +++ b/drivers/ssb/driver_chipcommon_pmu.c | |||
@@ -502,9 +502,9 @@ static void ssb_pmu_resources_init(struct ssb_chipcommon *cc) | |||
502 | chipco_write32(cc, SSB_CHIPCO_PMU_MAXRES_MSK, max_msk); | 502 | chipco_write32(cc, SSB_CHIPCO_PMU_MAXRES_MSK, max_msk); |
503 | } | 503 | } |
504 | 504 | ||
505 | /* http://bcm-v4.sipsolutions.net/802.11/SSB/PmuInit */ | ||
505 | void ssb_pmu_init(struct ssb_chipcommon *cc) | 506 | void ssb_pmu_init(struct ssb_chipcommon *cc) |
506 | { | 507 | { |
507 | struct ssb_bus *bus = cc->dev->bus; | ||
508 | u32 pmucap; | 508 | u32 pmucap; |
509 | 509 | ||
510 | if (!(cc->capabilities & SSB_CHIPCO_CAP_PMU)) | 510 | if (!(cc->capabilities & SSB_CHIPCO_CAP_PMU)) |
@@ -516,15 +516,12 @@ void ssb_pmu_init(struct ssb_chipcommon *cc) | |||
516 | ssb_dprintk(KERN_DEBUG PFX "Found rev %u PMU (capabilities 0x%08X)\n", | 516 | ssb_dprintk(KERN_DEBUG PFX "Found rev %u PMU (capabilities 0x%08X)\n", |
517 | cc->pmu.rev, pmucap); | 517 | cc->pmu.rev, pmucap); |
518 | 518 | ||
519 | if (cc->pmu.rev >= 1) { | 519 | if (cc->pmu.rev == 1) |
520 | if ((bus->chip_id == 0x4325) && (bus->chip_rev < 2)) { | 520 | chipco_mask32(cc, SSB_CHIPCO_PMU_CTL, |
521 | chipco_mask32(cc, SSB_CHIPCO_PMU_CTL, | 521 | ~SSB_CHIPCO_PMU_CTL_NOILPONW); |
522 | ~SSB_CHIPCO_PMU_CTL_NOILPONW); | 522 | else |
523 | } else { | 523 | chipco_set32(cc, SSB_CHIPCO_PMU_CTL, |
524 | chipco_set32(cc, SSB_CHIPCO_PMU_CTL, | 524 | SSB_CHIPCO_PMU_CTL_NOILPONW); |
525 | SSB_CHIPCO_PMU_CTL_NOILPONW); | ||
526 | } | ||
527 | } | ||
528 | ssb_pmu_pll_init(cc); | 525 | ssb_pmu_pll_init(cc); |
529 | ssb_pmu_resources_init(cc); | 526 | ssb_pmu_resources_init(cc); |
530 | } | 527 | } |
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 51275aac5b34..7cee7f4eb60b 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c | |||
@@ -486,6 +486,7 @@ static int ssb_devices_register(struct ssb_bus *bus) | |||
486 | #ifdef CONFIG_SSB_PCIHOST | 486 | #ifdef CONFIG_SSB_PCIHOST |
487 | sdev->irq = bus->host_pci->irq; | 487 | sdev->irq = bus->host_pci->irq; |
488 | dev->parent = &bus->host_pci->dev; | 488 | dev->parent = &bus->host_pci->dev; |
489 | sdev->dma_dev = dev->parent; | ||
489 | #endif | 490 | #endif |
490 | break; | 491 | break; |
491 | case SSB_BUSTYPE_PCMCIA: | 492 | case SSB_BUSTYPE_PCMCIA: |
@@ -501,6 +502,7 @@ static int ssb_devices_register(struct ssb_bus *bus) | |||
501 | break; | 502 | break; |
502 | case SSB_BUSTYPE_SSB: | 503 | case SSB_BUSTYPE_SSB: |
503 | dev->dma_mask = &dev->coherent_dma_mask; | 504 | dev->dma_mask = &dev->coherent_dma_mask; |
505 | sdev->dma_dev = dev; | ||
504 | break; | 506 | break; |
505 | } | 507 | } |
506 | 508 | ||
@@ -1226,80 +1228,6 @@ u32 ssb_dma_translation(struct ssb_device *dev) | |||
1226 | } | 1228 | } |
1227 | EXPORT_SYMBOL(ssb_dma_translation); | 1229 | EXPORT_SYMBOL(ssb_dma_translation); |
1228 | 1230 | ||
1229 | int ssb_dma_set_mask(struct ssb_device *dev, u64 mask) | ||
1230 | { | ||
1231 | #ifdef CONFIG_SSB_PCIHOST | ||
1232 | int err; | ||
1233 | #endif | ||
1234 | |||
1235 | switch (dev->bus->bustype) { | ||
1236 | case SSB_BUSTYPE_PCI: | ||
1237 | #ifdef CONFIG_SSB_PCIHOST | ||
1238 | err = pci_set_dma_mask(dev->bus->host_pci, mask); | ||
1239 | if (err) | ||
1240 | return err; | ||
1241 | err = pci_set_consistent_dma_mask(dev->bus->host_pci, mask); | ||
1242 | return err; | ||
1243 | #endif | ||
1244 | case SSB_BUSTYPE_SSB: | ||
1245 | return dma_set_mask(dev->dev, mask); | ||
1246 | default: | ||
1247 | __ssb_dma_not_implemented(dev); | ||
1248 | } | ||
1249 | return -ENOSYS; | ||
1250 | } | ||
1251 | EXPORT_SYMBOL(ssb_dma_set_mask); | ||
1252 | |||
1253 | void * ssb_dma_alloc_consistent(struct ssb_device *dev, size_t size, | ||
1254 | dma_addr_t *dma_handle, gfp_t gfp_flags) | ||
1255 | { | ||
1256 | switch (dev->bus->bustype) { | ||
1257 | case SSB_BUSTYPE_PCI: | ||
1258 | #ifdef CONFIG_SSB_PCIHOST | ||
1259 | if (gfp_flags & GFP_DMA) { | ||
1260 | /* Workaround: The PCI API does not support passing | ||
1261 | * a GFP flag. */ | ||
1262 | return dma_alloc_coherent(&dev->bus->host_pci->dev, | ||
1263 | size, dma_handle, gfp_flags); | ||
1264 | } | ||
1265 | return pci_alloc_consistent(dev->bus->host_pci, size, dma_handle); | ||
1266 | #endif | ||
1267 | case SSB_BUSTYPE_SSB: | ||
1268 | return dma_alloc_coherent(dev->dev, size, dma_handle, gfp_flags); | ||
1269 | default: | ||
1270 | __ssb_dma_not_implemented(dev); | ||
1271 | } | ||
1272 | return NULL; | ||
1273 | } | ||
1274 | EXPORT_SYMBOL(ssb_dma_alloc_consistent); | ||
1275 | |||
1276 | void ssb_dma_free_consistent(struct ssb_device *dev, size_t size, | ||
1277 | void *vaddr, dma_addr_t dma_handle, | ||
1278 | gfp_t gfp_flags) | ||
1279 | { | ||
1280 | switch (dev->bus->bustype) { | ||
1281 | case SSB_BUSTYPE_PCI: | ||
1282 | #ifdef CONFIG_SSB_PCIHOST | ||
1283 | if (gfp_flags & GFP_DMA) { | ||
1284 | /* Workaround: The PCI API does not support passing | ||
1285 | * a GFP flag. */ | ||
1286 | dma_free_coherent(&dev->bus->host_pci->dev, | ||
1287 | size, vaddr, dma_handle); | ||
1288 | return; | ||
1289 | } | ||
1290 | pci_free_consistent(dev->bus->host_pci, size, | ||
1291 | vaddr, dma_handle); | ||
1292 | return; | ||
1293 | #endif | ||
1294 | case SSB_BUSTYPE_SSB: | ||
1295 | dma_free_coherent(dev->dev, size, vaddr, dma_handle); | ||
1296 | return; | ||
1297 | default: | ||
1298 | __ssb_dma_not_implemented(dev); | ||
1299 | } | ||
1300 | } | ||
1301 | EXPORT_SYMBOL(ssb_dma_free_consistent); | ||
1302 | |||
1303 | int ssb_bus_may_powerdown(struct ssb_bus *bus) | 1231 | int ssb_bus_may_powerdown(struct ssb_bus *bus) |
1304 | { | 1232 | { |
1305 | struct ssb_chipcommon *cc; | 1233 | struct ssb_chipcommon *cc; |
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 6dcda86be6eb..6e88d2b603b4 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c | |||
@@ -626,11 +626,22 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, | |||
626 | return -ENODEV; | 626 | return -ENODEV; |
627 | } | 627 | } |
628 | if (bus->chipco.dev) { /* can be unavailible! */ | 628 | if (bus->chipco.dev) { /* can be unavailible! */ |
629 | bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ? | 629 | /* |
630 | SSB_SPROM_BASE1 : SSB_SPROM_BASE31; | 630 | * get SPROM offset: SSB_SPROM_BASE1 except for |
631 | * chipcommon rev >= 31 or chip ID is 0x4312 and | ||
632 | * chipcommon status & 3 == 2 | ||
633 | */ | ||
634 | if (bus->chipco.dev->id.revision >= 31) | ||
635 | bus->sprom_offset = SSB_SPROM_BASE31; | ||
636 | else if (bus->chip_id == 0x4312 && | ||
637 | (bus->chipco.status & 0x03) == 2) | ||
638 | bus->sprom_offset = SSB_SPROM_BASE31; | ||
639 | else | ||
640 | bus->sprom_offset = SSB_SPROM_BASE1; | ||
631 | } else { | 641 | } else { |
632 | bus->sprom_offset = SSB_SPROM_BASE1; | 642 | bus->sprom_offset = SSB_SPROM_BASE1; |
633 | } | 643 | } |
644 | ssb_dprintk(KERN_INFO PFX "SPROM offset is 0x%x\n", bus->sprom_offset); | ||
634 | 645 | ||
635 | buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); | 646 | buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); |
636 | if (!buf) | 647 | if (!buf) |