aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-14 17:27:45 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-14 17:27:45 -0500
commitcebfa85eb86d92bf85d3b041c6b044184517a988 (patch)
treebe0a374556fe335ce96dfdb296c89537750d5868 /drivers/ssb
parentd42b3a2906a10b732ea7d7f849d49be79d242ef0 (diff)
parent241738bd51cb0efe58e6c570223153e970afe3ae (diff)
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle: "The MIPS bits for 3.8. This also includes a bunch fixes that were sitting in the linux-mips.org git tree for a long time. This pull request contains updates to several OCTEON drivers and the board support code for BCM47XX, BCM63XX, XLP, XLR, XLS, lantiq, Loongson1B, updates to the SSB bus support, MIPS kexec code and adds support for kdump. When pulling this, there are two expected merge conflicts in include/linux/bcma/bcma_driver_chipcommon.h which are trivial to resolve, just remove the conflict markers and keep both alternatives." * 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (90 commits) MIPS: PMC-Sierra Yosemite: Remove support. VIDEO: Newport Fix console crashes MIPS: wrppmc: Fix build of PCI code. MIPS: IP22/IP28: Fix build of EISA code. MIPS: RB532: Fix build of prom code. MIPS: PowerTV: Fix build. MIPS: IP27: Correct fucked grammar in ops-bridge.c MIPS: Highmem: Fix build error if CONFIG_DEBUG_HIGHMEM is disabled MIPS: Fix potencial corruption MIPS: Fix for warning from FPU emulation code MIPS: Handle COP3 Unusable exception as COP1X for FP emulation MIPS: Fix poweroff failure when HOTPLUG_CPU configured. MIPS: MT: Fix build with CONFIG_UIDGID_STRICT_TYPE_CHECKS=y MIPS: Remove unused smvp.h MIPS/EDAC: Improve OCTEON EDAC support. MIPS: OCTEON: Add definitions for OCTEON memory contoller registers. MIPS: OCTEON: Add OCTEON family definitions to octeon-model.h ata: pata_octeon_cf: Use correct byte order for DMA in when built little-endian. MIPS/OCTEON/ata: Convert pata_octeon_cf.c to use device tree. MIPS: Remove usage of CEVT_R4K_LIB config option. ...
Diffstat (limited to 'drivers/ssb')
-rw-r--r--drivers/ssb/Kconfig9
-rw-r--r--drivers/ssb/Makefile1
-rw-r--r--drivers/ssb/driver_chipcommon.c78
-rw-r--r--drivers/ssb/driver_extif.c43
-rw-r--r--drivers/ssb/driver_gpio.c176
-rw-r--r--drivers/ssb/main.c7
-rw-r--r--drivers/ssb/ssb_private.h17
7 files changed, 322 insertions, 9 deletions
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig
index 42cdaa9a4d8a..ff3c8a21f10d 100644
--- a/drivers/ssb/Kconfig
+++ b/drivers/ssb/Kconfig
@@ -160,4 +160,13 @@ config SSB_DRIVER_GIGE
160 160
161 If unsure, say N 161 If unsure, say N
162 162
163config SSB_DRIVER_GPIO
164 bool "SSB GPIO driver"
165 depends on SSB
166 select GPIOLIB
167 help
168 Driver to provide access to the GPIO pins on the bus.
169
170 If unsure, say N
171
163endmenu 172endmenu
diff --git a/drivers/ssb/Makefile b/drivers/ssb/Makefile
index 656e58b92618..9159ba77c388 100644
--- a/drivers/ssb/Makefile
+++ b/drivers/ssb/Makefile
@@ -15,6 +15,7 @@ ssb-$(CONFIG_SSB_DRIVER_MIPS) += driver_mipscore.o
15ssb-$(CONFIG_SSB_DRIVER_EXTIF) += driver_extif.o 15ssb-$(CONFIG_SSB_DRIVER_EXTIF) += driver_extif.o
16ssb-$(CONFIG_SSB_DRIVER_PCICORE) += driver_pcicore.o 16ssb-$(CONFIG_SSB_DRIVER_PCICORE) += driver_pcicore.o
17ssb-$(CONFIG_SSB_DRIVER_GIGE) += driver_gige.o 17ssb-$(CONFIG_SSB_DRIVER_GIGE) += driver_gige.o
18ssb-$(CONFIG_SSB_DRIVER_GPIO) += driver_gpio.o
18 19
19# b43 pci-ssb-bridge driver 20# b43 pci-ssb-bridge driver
20# Not strictly a part of SSB, but kept here for convenience 21# Not strictly a part of SSB, but kept here for convenience
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
index 95c33a05f434..71098a7b5fed 100644
--- a/drivers/ssb/driver_chipcommon.c
+++ b/drivers/ssb/driver_chipcommon.c
@@ -349,6 +349,9 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc)
349{ 349{
350 if (!cc->dev) 350 if (!cc->dev)
351 return; /* We don't have a ChipCommon */ 351 return; /* We don't have a ChipCommon */
352
353 spin_lock_init(&cc->gpio_lock);
354
352 if (cc->dev->id.revision >= 11) 355 if (cc->dev->id.revision >= 11)
353 cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); 356 cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
354 ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status); 357 ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status);
@@ -505,28 +508,93 @@ u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask)
505 508
506u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value) 509u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value)
507{ 510{
508 return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value); 511 unsigned long flags;
512 u32 res = 0;
513
514 spin_lock_irqsave(&cc->gpio_lock, flags);
515 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value);
516 spin_unlock_irqrestore(&cc->gpio_lock, flags);
517
518 return res;
509} 519}
510 520
511u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value) 521u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value)
512{ 522{
513 return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value); 523 unsigned long flags;
524 u32 res = 0;
525
526 spin_lock_irqsave(&cc->gpio_lock, flags);
527 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value);
528 spin_unlock_irqrestore(&cc->gpio_lock, flags);
529
530 return res;
514} 531}
515 532
516u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value) 533u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value)
517{ 534{
518 return chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value); 535 unsigned long flags;
536 u32 res = 0;
537
538 spin_lock_irqsave(&cc->gpio_lock, flags);
539 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value);
540 spin_unlock_irqrestore(&cc->gpio_lock, flags);
541
542 return res;
519} 543}
520EXPORT_SYMBOL(ssb_chipco_gpio_control); 544EXPORT_SYMBOL(ssb_chipco_gpio_control);
521 545
522u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value) 546u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value)
523{ 547{
524 return chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value); 548 unsigned long flags;
549 u32 res = 0;
550
551 spin_lock_irqsave(&cc->gpio_lock, flags);
552 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value);
553 spin_unlock_irqrestore(&cc->gpio_lock, flags);
554
555 return res;
525} 556}
526 557
527u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value) 558u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value)
528{ 559{
529 return chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value); 560 unsigned long flags;
561 u32 res = 0;
562
563 spin_lock_irqsave(&cc->gpio_lock, flags);
564 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value);
565 spin_unlock_irqrestore(&cc->gpio_lock, flags);
566
567 return res;
568}
569
570u32 ssb_chipco_gpio_pullup(struct ssb_chipcommon *cc, u32 mask, u32 value)
571{
572 unsigned long flags;
573 u32 res = 0;
574
575 if (cc->dev->id.revision < 20)
576 return 0xffffffff;
577
578 spin_lock_irqsave(&cc->gpio_lock, flags);
579 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLUP, mask, value);
580 spin_unlock_irqrestore(&cc->gpio_lock, flags);
581
582 return res;
583}
584
585u32 ssb_chipco_gpio_pulldown(struct ssb_chipcommon *cc, u32 mask, u32 value)
586{
587 unsigned long flags;
588 u32 res = 0;
589
590 if (cc->dev->id.revision < 20)
591 return 0xffffffff;
592
593 spin_lock_irqsave(&cc->gpio_lock, flags);
594 res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLDOWN, mask, value);
595 spin_unlock_irqrestore(&cc->gpio_lock, flags);
596
597 return res;
530} 598}
531 599
532#ifdef CONFIG_SSB_SERIAL 600#ifdef CONFIG_SSB_SERIAL
diff --git a/drivers/ssb/driver_extif.c b/drivers/ssb/driver_extif.c
index 553227a3062d..59385fdab5b0 100644
--- a/drivers/ssb/driver_extif.c
+++ b/drivers/ssb/driver_extif.c
@@ -138,6 +138,13 @@ u32 ssb_extif_watchdog_timer_set(struct ssb_extif *extif, u32 ticks)
138 return ticks; 138 return ticks;
139} 139}
140 140
141void ssb_extif_init(struct ssb_extif *extif)
142{
143 if (!extif->dev)
144 return; /* We don't have a Extif core */
145 spin_lock_init(&extif->gpio_lock);
146}
147
141u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask) 148u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask)
142{ 149{
143 return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask; 150 return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask;
@@ -145,22 +152,50 @@ u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask)
145 152
146u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value) 153u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value)
147{ 154{
148 return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0), 155 unsigned long flags;
156 u32 res = 0;
157
158 spin_lock_irqsave(&extif->gpio_lock, flags);
159 res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0),
149 mask, value); 160 mask, value);
161 spin_unlock_irqrestore(&extif->gpio_lock, flags);
162
163 return res;
150} 164}
151 165
152u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value) 166u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value)
153{ 167{
154 return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0), 168 unsigned long flags;
169 u32 res = 0;
170
171 spin_lock_irqsave(&extif->gpio_lock, flags);
172 res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0),
155 mask, value); 173 mask, value);
174 spin_unlock_irqrestore(&extif->gpio_lock, flags);
175
176 return res;
156} 177}
157 178
158u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value) 179u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value)
159{ 180{
160 return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value); 181 unsigned long flags;
182 u32 res = 0;
183
184 spin_lock_irqsave(&extif->gpio_lock, flags);
185 res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value);
186 spin_unlock_irqrestore(&extif->gpio_lock, flags);
187
188 return res;
161} 189}
162 190
163u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value) 191u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value)
164{ 192{
165 return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value); 193 unsigned long flags;
194 u32 res = 0;
195
196 spin_lock_irqsave(&extif->gpio_lock, flags);
197 res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value);
198 spin_unlock_irqrestore(&extif->gpio_lock, flags);
199
200 return res;
166} 201}
diff --git a/drivers/ssb/driver_gpio.c b/drivers/ssb/driver_gpio.c
new file mode 100644
index 000000000000..97ac0a38e3d0
--- /dev/null
+++ b/drivers/ssb/driver_gpio.c
@@ -0,0 +1,176 @@
1/*
2 * Sonics Silicon Backplane
3 * GPIO driver
4 *
5 * Copyright 2011, Broadcom Corporation
6 * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
7 *
8 * Licensed under the GNU/GPL. See COPYING for details.
9 */
10
11#include <linux/gpio.h>
12#include <linux/export.h>
13#include <linux/ssb/ssb.h>
14
15#include "ssb_private.h"
16
17static struct ssb_bus *ssb_gpio_get_bus(struct gpio_chip *chip)
18{
19 return container_of(chip, struct ssb_bus, gpio);
20}
21
22static int ssb_gpio_chipco_get_value(struct gpio_chip *chip, unsigned gpio)
23{
24 struct ssb_bus *bus = ssb_gpio_get_bus(chip);
25
26 return !!ssb_chipco_gpio_in(&bus->chipco, 1 << gpio);
27}
28
29static void ssb_gpio_chipco_set_value(struct gpio_chip *chip, unsigned gpio,
30 int value)
31{
32 struct ssb_bus *bus = ssb_gpio_get_bus(chip);
33
34 ssb_chipco_gpio_out(&bus->chipco, 1 << gpio, value ? 1 << gpio : 0);
35}
36
37static int ssb_gpio_chipco_direction_input(struct gpio_chip *chip,
38 unsigned gpio)
39{
40 struct ssb_bus *bus = ssb_gpio_get_bus(chip);
41
42 ssb_chipco_gpio_outen(&bus->chipco, 1 << gpio, 0);
43 return 0;
44}
45
46static int ssb_gpio_chipco_direction_output(struct gpio_chip *chip,
47 unsigned gpio, int value)
48{
49 struct ssb_bus *bus = ssb_gpio_get_bus(chip);
50
51 ssb_chipco_gpio_outen(&bus->chipco, 1 << gpio, 1 << gpio);
52 ssb_chipco_gpio_out(&bus->chipco, 1 << gpio, value ? 1 << gpio : 0);
53 return 0;
54}
55
56static int ssb_gpio_chipco_request(struct gpio_chip *chip, unsigned gpio)
57{
58 struct ssb_bus *bus = ssb_gpio_get_bus(chip);
59
60 ssb_chipco_gpio_control(&bus->chipco, 1 << gpio, 0);
61 /* clear pulldown */
62 ssb_chipco_gpio_pulldown(&bus->chipco, 1 << gpio, 0);
63 /* Set pullup */
64 ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 1 << gpio);
65
66 return 0;
67}
68
69static void ssb_gpio_chipco_free(struct gpio_chip *chip, unsigned gpio)
70{
71 struct ssb_bus *bus = ssb_gpio_get_bus(chip);
72
73 /* clear pullup */
74 ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 0);
75}
76
77static int ssb_gpio_chipco_init(struct ssb_bus *bus)
78{
79 struct gpio_chip *chip = &bus->gpio;
80
81 chip->label = "ssb_chipco_gpio";
82 chip->owner = THIS_MODULE;
83 chip->request = ssb_gpio_chipco_request;
84 chip->free = ssb_gpio_chipco_free;
85 chip->get = ssb_gpio_chipco_get_value;
86 chip->set = ssb_gpio_chipco_set_value;
87 chip->direction_input = ssb_gpio_chipco_direction_input;
88 chip->direction_output = ssb_gpio_chipco_direction_output;
89 chip->ngpio = 16;
90 /* There is just one SoC in one device and its GPIO addresses should be
91 * deterministic to address them more easily. The other buses could get
92 * a random base number. */
93 if (bus->bustype == SSB_BUSTYPE_SSB)
94 chip->base = 0;
95 else
96 chip->base = -1;
97
98 return gpiochip_add(chip);
99}
100
101#ifdef CONFIG_SSB_DRIVER_EXTIF
102
103static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned gpio)
104{
105 struct ssb_bus *bus = ssb_gpio_get_bus(chip);
106
107 return !!ssb_extif_gpio_in(&bus->extif, 1 << gpio);
108}
109
110static void ssb_gpio_extif_set_value(struct gpio_chip *chip, unsigned gpio,
111 int value)
112{
113 struct ssb_bus *bus = ssb_gpio_get_bus(chip);
114
115 ssb_extif_gpio_out(&bus->extif, 1 << gpio, value ? 1 << gpio : 0);
116}
117
118static int ssb_gpio_extif_direction_input(struct gpio_chip *chip,
119 unsigned gpio)
120{
121 struct ssb_bus *bus = ssb_gpio_get_bus(chip);
122
123 ssb_extif_gpio_outen(&bus->extif, 1 << gpio, 0);
124 return 0;
125}
126
127static int ssb_gpio_extif_direction_output(struct gpio_chip *chip,
128 unsigned gpio, int value)
129{
130 struct ssb_bus *bus = ssb_gpio_get_bus(chip);
131
132 ssb_extif_gpio_outen(&bus->extif, 1 << gpio, 1 << gpio);
133 ssb_extif_gpio_out(&bus->extif, 1 << gpio, value ? 1 << gpio : 0);
134 return 0;
135}
136
137static int ssb_gpio_extif_init(struct ssb_bus *bus)
138{
139 struct gpio_chip *chip = &bus->gpio;
140
141 chip->label = "ssb_extif_gpio";
142 chip->owner = THIS_MODULE;
143 chip->get = ssb_gpio_extif_get_value;
144 chip->set = ssb_gpio_extif_set_value;
145 chip->direction_input = ssb_gpio_extif_direction_input;
146 chip->direction_output = ssb_gpio_extif_direction_output;
147 chip->ngpio = 5;
148 /* There is just one SoC in one device and its GPIO addresses should be
149 * deterministic to address them more easily. The other buses could get
150 * a random base number. */
151 if (bus->bustype == SSB_BUSTYPE_SSB)
152 chip->base = 0;
153 else
154 chip->base = -1;
155
156 return gpiochip_add(chip);
157}
158
159#else
160static int ssb_gpio_extif_init(struct ssb_bus *bus)
161{
162 return -ENOTSUPP;
163}
164#endif
165
166int ssb_gpio_init(struct ssb_bus *bus)
167{
168 if (ssb_chipco_available(&bus->chipco))
169 return ssb_gpio_chipco_init(bus);
170 else if (ssb_extif_available(&bus->extif))
171 return ssb_gpio_extif_init(bus);
172 else
173 SSB_WARN_ON(1);
174
175 return -1;
176}
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 6e0daaa0e04b..c82c5c95fe85 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -804,7 +804,14 @@ static int __devinit ssb_bus_register(struct ssb_bus *bus,
804 if (err) 804 if (err)
805 goto err_pcmcia_exit; 805 goto err_pcmcia_exit;
806 ssb_chipcommon_init(&bus->chipco); 806 ssb_chipcommon_init(&bus->chipco);
807 ssb_extif_init(&bus->extif);
807 ssb_mipscore_init(&bus->mipscore); 808 ssb_mipscore_init(&bus->mipscore);
809 err = ssb_gpio_init(bus);
810 if (err == -ENOTSUPP)
811 ssb_dprintk(KERN_DEBUG PFX "GPIO driver not activated\n");
812 else if (err)
813 ssb_dprintk(KERN_ERR PFX
814 "Error registering GPIO driver: %i\n", err);
808 err = ssb_fetch_invariants(bus, get_invariants); 815 err = ssb_fetch_invariants(bus, get_invariants);
809 if (err) { 816 if (err) {
810 ssb_bus_may_powerdown(bus); 817 ssb_bus_may_powerdown(bus);
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h
index 8942db1d855a..6c10b66c796c 100644
--- a/drivers/ssb/ssb_private.h
+++ b/drivers/ssb/ssb_private.h
@@ -242,4 +242,21 @@ static inline int ssb_watchdog_register(struct ssb_bus *bus)
242} 242}
243#endif /* CONFIG_SSB_EMBEDDED */ 243#endif /* CONFIG_SSB_EMBEDDED */
244 244
245#ifdef CONFIG_SSB_DRIVER_EXTIF
246extern void ssb_extif_init(struct ssb_extif *extif);
247#else
248static inline void ssb_extif_init(struct ssb_extif *extif)
249{
250}
251#endif
252
253#ifdef CONFIG_SSB_DRIVER_GPIO
254extern int ssb_gpio_init(struct ssb_bus *bus);
255#else /* CONFIG_SSB_DRIVER_GPIO */
256static inline int ssb_gpio_init(struct ssb_bus *bus)
257{
258 return -ENOTSUPP;
259}
260#endif /* CONFIG_SSB_DRIVER_GPIO */
261
245#endif /* LINUX_SSB_PRIVATE_H_ */ 262#endif /* LINUX_SSB_PRIVATE_H_ */