aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ssb')
-rw-r--r--drivers/ssb/driver_chipcommon.c25
-rw-r--r--drivers/ssb/driver_chipcommon_pmu.c17
-rw-r--r--drivers/ssb/main.c76
-rw-r--r--drivers/ssb/pci.c15
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 */
213static 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 */
212static void calc_fast_powerup_delay(struct ssb_chipcommon *cc) 230static 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 */
505void ssb_pmu_init(struct ssb_chipcommon *cc) 506void 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}
1227EXPORT_SYMBOL(ssb_dma_translation); 1229EXPORT_SYMBOL(ssb_dma_translation);
1228 1230
1229int 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}
1251EXPORT_SYMBOL(ssb_dma_set_mask);
1252
1253void * 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}
1274EXPORT_SYMBOL(ssb_dma_alloc_consistent);
1275
1276void 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}
1301EXPORT_SYMBOL(ssb_dma_free_consistent);
1302
1303int ssb_bus_may_powerdown(struct ssb_bus *bus) 1231int 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)