aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ssb')
-rw-r--r--drivers/ssb/driver_chipcommon.c66
-rw-r--r--drivers/ssb/driver_extif.c43
-rw-r--r--drivers/ssb/main.c1
-rw-r--r--drivers/ssb/ssb_private.h8
4 files changed, 107 insertions, 11 deletions
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
index 4df492665565..24e02bb2ecd8 100644
--- a/drivers/ssb/driver_chipcommon.c
+++ b/drivers/ssb/driver_chipcommon.c
@@ -284,6 +284,9 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc)
284{ 284{
285 if (!cc->dev) 285 if (!cc->dev)
286 return; /* We don't have a ChipCommon */ 286 return; /* We don't have a ChipCommon */
287
288 spin_lock_init(&cc->gpio_lock);
289
287 if (cc->dev->id.revision >= 11) 290 if (cc->dev->id.revision >= 11)
288 cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); 291 cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
289 ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status); 292 ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status);
@@ -418,44 +421,93 @@ u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask)
418 421
419u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value) 422u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value)
420{ 423{
421 return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value); 424 unsigned long flags;
425 u32 res = 0;
426
427 spin_lock_irqsave(&cc->gpio_lock, flags);
428 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value);
429 spin_unlock_irqrestore(&cc->gpio_lock, flags);
430
431 return res;
422} 432}
423 433
424u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value) 434u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value)
425{ 435{
426 return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value); 436 unsigned long flags;
437 u32 res = 0;
438
439 spin_lock_irqsave(&cc->gpio_lock, flags);
440 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value);
441 spin_unlock_irqrestore(&cc->gpio_lock, flags);
442
443 return res;
427} 444}
428 445
429u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value) 446u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value)
430{ 447{
431 return chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value); 448 unsigned long flags;
449 u32 res = 0;
450
451 spin_lock_irqsave(&cc->gpio_lock, flags);
452 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value);
453 spin_unlock_irqrestore(&cc->gpio_lock, flags);
454
455 return res;
432} 456}
433EXPORT_SYMBOL(ssb_chipco_gpio_control); 457EXPORT_SYMBOL(ssb_chipco_gpio_control);
434 458
435u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value) 459u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value)
436{ 460{
437 return chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value); 461 unsigned long flags;
462 u32 res = 0;
463
464 spin_lock_irqsave(&cc->gpio_lock, flags);
465 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value);
466 spin_unlock_irqrestore(&cc->gpio_lock, flags);
467
468 return res;
438} 469}
439 470
440u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value) 471u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value)
441{ 472{
442 return chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value); 473 unsigned long flags;
474 u32 res = 0;
475
476 spin_lock_irqsave(&cc->gpio_lock, flags);
477 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value);
478 spin_unlock_irqrestore(&cc->gpio_lock, flags);
479
480 return res;
443} 481}
444 482
445u32 ssb_chipco_gpio_pullup(struct ssb_chipcommon *cc, u32 mask, u32 value) 483u32 ssb_chipco_gpio_pullup(struct ssb_chipcommon *cc, u32 mask, u32 value)
446{ 484{
485 unsigned long flags;
486 u32 res = 0;
487
447 if (cc->dev->id.revision < 20) 488 if (cc->dev->id.revision < 20)
448 return 0xffffffff; 489 return 0xffffffff;
449 490
450 return chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLUP, mask, value); 491 spin_lock_irqsave(&cc->gpio_lock, flags);
492 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLUP, mask, value);
493 spin_unlock_irqrestore(&cc->gpio_lock, flags);
494
495 return res;
451} 496}
452 497
453u32 ssb_chipco_gpio_pulldown(struct ssb_chipcommon *cc, u32 mask, u32 value) 498u32 ssb_chipco_gpio_pulldown(struct ssb_chipcommon *cc, u32 mask, u32 value)
454{ 499{
500 unsigned long flags;
501 u32 res = 0;
502
455 if (cc->dev->id.revision < 20) 503 if (cc->dev->id.revision < 20)
456 return 0xffffffff; 504 return 0xffffffff;
457 505
458 return chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLDOWN, mask, value); 506 spin_lock_irqsave(&cc->gpio_lock, flags);
507 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLDOWN, mask, value);
508 spin_unlock_irqrestore(&cc->gpio_lock, flags);
509
510 return res;
459} 511}
460 512
461#ifdef CONFIG_SSB_SERIAL 513#ifdef CONFIG_SSB_SERIAL
diff --git a/drivers/ssb/driver_extif.c b/drivers/ssb/driver_extif.c
index dc47f30e9cf7..e1d0bb8ad725 100644
--- a/drivers/ssb/driver_extif.c
+++ b/drivers/ssb/driver_extif.c
@@ -118,6 +118,13 @@ void ssb_extif_watchdog_timer_set(struct ssb_extif *extif,
118 extif_write32(extif, SSB_EXTIF_WATCHDOG, ticks); 118 extif_write32(extif, SSB_EXTIF_WATCHDOG, ticks);
119} 119}
120 120
121void ssb_extif_init(struct ssb_extif *extif)
122{
123 if (!extif->dev)
124 return; /* We don't have a Extif core */
125 spin_lock_init(&extif->gpio_lock);
126}
127
121u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask) 128u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask)
122{ 129{
123 return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask; 130 return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask;
@@ -125,22 +132,50 @@ u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask)
125 132
126u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value) 133u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value)
127{ 134{
128 return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0), 135 unsigned long flags;
136 u32 res = 0;
137
138 spin_lock_irqsave(&extif->gpio_lock, flags);
139 res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0),
129 mask, value); 140 mask, value);
141 spin_unlock_irqrestore(&extif->gpio_lock, flags);
142
143 return res;
130} 144}
131 145
132u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value) 146u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value)
133{ 147{
134 return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0), 148 unsigned long flags;
149 u32 res = 0;
150
151 spin_lock_irqsave(&extif->gpio_lock, flags);
152 res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0),
135 mask, value); 153 mask, value);
154 spin_unlock_irqrestore(&extif->gpio_lock, flags);
155
156 return res;
136} 157}
137 158
138u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value) 159u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value)
139{ 160{
140 return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value); 161 unsigned long flags;
162 u32 res = 0;
163
164 spin_lock_irqsave(&extif->gpio_lock, flags);
165 res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value);
166 spin_unlock_irqrestore(&extif->gpio_lock, flags);
167
168 return res;
141} 169}
142 170
143u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value) 171u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value)
144{ 172{
145 return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value); 173 unsigned long flags;
174 u32 res = 0;
175
176 spin_lock_irqsave(&extif->gpio_lock, flags);
177 res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value);
178 spin_unlock_irqrestore(&extif->gpio_lock, flags);
179
180 return res;
146} 181}
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index df0f145c22fc..6fe2d102734a 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -796,6 +796,7 @@ static int __devinit ssb_bus_register(struct ssb_bus *bus,
796 if (err) 796 if (err)
797 goto err_pcmcia_exit; 797 goto err_pcmcia_exit;
798 ssb_chipcommon_init(&bus->chipco); 798 ssb_chipcommon_init(&bus->chipco);
799 ssb_extif_init(&bus->extif);
799 ssb_mipscore_init(&bus->mipscore); 800 ssb_mipscore_init(&bus->mipscore);
800 err = ssb_fetch_invariants(bus, get_invariants); 801 err = ssb_fetch_invariants(bus, get_invariants);
801 if (err) { 802 if (err) {
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h
index a305550b4b65..d6a1ba9394d9 100644
--- a/drivers/ssb/ssb_private.h
+++ b/drivers/ssb/ssb_private.h
@@ -211,4 +211,12 @@ static inline void b43_pci_ssb_bridge_exit(void)
211extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc); 211extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc);
212extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc); 212extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc);
213 213
214#ifdef CONFIG_SSB_DRIVER_EXTIF
215extern void ssb_extif_init(struct ssb_extif *extif);
216#else
217static inline void ssb_extif_init(struct ssb_extif *extif)
218{
219}
220#endif
221
214#endif /* LINUX_SSB_PRIVATE_H_ */ 222#endif /* LINUX_SSB_PRIVATE_H_ */