diff options
Diffstat (limited to 'drivers/ssb')
-rw-r--r-- | drivers/ssb/driver_chipcommon.c | 66 | ||||
-rw-r--r-- | drivers/ssb/driver_extif.c | 43 | ||||
-rw-r--r-- | drivers/ssb/main.c | 1 | ||||
-rw-r--r-- | drivers/ssb/ssb_private.h | 8 |
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 | ||
419 | u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value) | 422 | u32 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 | ||
424 | u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value) | 434 | u32 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 | ||
429 | u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value) | 446 | u32 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 | } |
433 | EXPORT_SYMBOL(ssb_chipco_gpio_control); | 457 | EXPORT_SYMBOL(ssb_chipco_gpio_control); |
434 | 458 | ||
435 | u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value) | 459 | u32 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 | ||
440 | u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value) | 471 | u32 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 | ||
445 | u32 ssb_chipco_gpio_pullup(struct ssb_chipcommon *cc, u32 mask, u32 value) | 483 | u32 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 | ||
453 | u32 ssb_chipco_gpio_pulldown(struct ssb_chipcommon *cc, u32 mask, u32 value) | 498 | u32 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 | ||
121 | void 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 | |||
121 | u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask) | 128 | u32 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 | ||
126 | u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value) | 133 | u32 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 | ||
132 | u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value) | 146 | u32 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 | ||
138 | u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value) | 159 | u32 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 | ||
143 | u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value) | 171 | u32 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) | |||
211 | extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc); | 211 | extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc); |
212 | extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc); | 212 | extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc); |
213 | 213 | ||
214 | #ifdef CONFIG_SSB_DRIVER_EXTIF | ||
215 | extern void ssb_extif_init(struct ssb_extif *extif); | ||
216 | #else | ||
217 | static 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_ */ |