aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2014-01-13 13:56:08 -0500
committerRalf Baechle <ralf@linux-mips.org>2014-01-24 16:39:54 -0500
commit7c1bc0da3206de789a71c4aae8ac44d580bc5578 (patch)
tree4b73ed9000e7b1f1dbff5f6530b163ac7de1158b /drivers/ssb
parent89fb3ac8621ba78cf11cc7bb1eb0991d204d5b18 (diff)
ssb: gpio: add own IRQ domain
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Acked-by: Hauke Mehrtens <hauke@hauke-m.de> Acked-by: Michael Buesch <m@bues.ch> Signed-off-by: John Crispin <blogic@openwrt.org> Patchwork: http://patchwork.linux-mips.org/patch/6342/
Diffstat (limited to 'drivers/ssb')
-rw-r--r--drivers/ssb/Kconfig1
-rw-r--r--drivers/ssb/driver_gpio.c306
-rw-r--r--drivers/ssb/main.c12
3 files changed, 298 insertions, 21 deletions
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig
index 2cd9b0e44a41..75b3603906c1 100644
--- a/drivers/ssb/Kconfig
+++ b/drivers/ssb/Kconfig
@@ -168,6 +168,7 @@ config SSB_DRIVER_GIGE
168config SSB_DRIVER_GPIO 168config SSB_DRIVER_GPIO
169 bool "SSB GPIO driver" 169 bool "SSB GPIO driver"
170 depends on SSB && GPIOLIB 170 depends on SSB && GPIOLIB
171 select IRQ_DOMAIN if SSB_EMBEDDED
171 help 172 help
172 Driver to provide access to the GPIO pins on the bus. 173 Driver to provide access to the GPIO pins on the bus.
173 174
diff --git a/drivers/ssb/driver_gpio.c b/drivers/ssb/driver_gpio.c
index dc109de228c6..ba350d2035c0 100644
--- a/drivers/ssb/driver_gpio.c
+++ b/drivers/ssb/driver_gpio.c
@@ -9,16 +9,40 @@
9 */ 9 */
10 10
11#include <linux/gpio.h> 11#include <linux/gpio.h>
12#include <linux/irq.h>
13#include <linux/interrupt.h>
14#include <linux/irqdomain.h>
12#include <linux/export.h> 15#include <linux/export.h>
13#include <linux/ssb/ssb.h> 16#include <linux/ssb/ssb.h>
14 17
15#include "ssb_private.h" 18#include "ssb_private.h"
16 19
20
21/**************************************************
22 * Shared
23 **************************************************/
24
17static struct ssb_bus *ssb_gpio_get_bus(struct gpio_chip *chip) 25static struct ssb_bus *ssb_gpio_get_bus(struct gpio_chip *chip)
18{ 26{
19 return container_of(chip, struct ssb_bus, gpio); 27 return container_of(chip, struct ssb_bus, gpio);
20} 28}
21 29
30#if IS_ENABLED(CONFIG_SSB_EMBEDDED)
31static int ssb_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
32{
33 struct ssb_bus *bus = ssb_gpio_get_bus(chip);
34
35 if (bus->bustype == SSB_BUSTYPE_SSB)
36 return irq_find_mapping(bus->irq_domain, gpio);
37 else
38 return -EINVAL;
39}
40#endif
41
42/**************************************************
43 * ChipCommon
44 **************************************************/
45
22static int ssb_gpio_chipco_get_value(struct gpio_chip *chip, unsigned gpio) 46static int ssb_gpio_chipco_get_value(struct gpio_chip *chip, unsigned gpio)
23{ 47{
24 struct ssb_bus *bus = ssb_gpio_get_bus(chip); 48 struct ssb_bus *bus = ssb_gpio_get_bus(chip);
@@ -74,19 +98,129 @@ static void ssb_gpio_chipco_free(struct gpio_chip *chip, unsigned gpio)
74 ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 0); 98 ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 0);
75} 99}
76 100
77static int ssb_gpio_chipco_to_irq(struct gpio_chip *chip, unsigned gpio) 101#if IS_ENABLED(CONFIG_SSB_EMBEDDED)
102static void ssb_gpio_irq_chipco_mask(struct irq_data *d)
78{ 103{
79 struct ssb_bus *bus = ssb_gpio_get_bus(chip); 104 struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
105 int gpio = irqd_to_hwirq(d);
80 106
81 if (bus->bustype == SSB_BUSTYPE_SSB) 107 ssb_chipco_gpio_intmask(&bus->chipco, BIT(gpio), 0);
82 return ssb_mips_irq(bus->chipco.dev) + 2; 108}
83 else 109
84 return -EINVAL; 110static void ssb_gpio_irq_chipco_unmask(struct irq_data *d)
111{
112 struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
113 int gpio = irqd_to_hwirq(d);
114 u32 val = ssb_chipco_gpio_in(&bus->chipco, BIT(gpio));
115
116 ssb_chipco_gpio_polarity(&bus->chipco, BIT(gpio), val);
117 ssb_chipco_gpio_intmask(&bus->chipco, BIT(gpio), BIT(gpio));
118}
119
120static struct irq_chip ssb_gpio_irq_chipco_chip = {
121 .name = "SSB-GPIO-CC",
122 .irq_mask = ssb_gpio_irq_chipco_mask,
123 .irq_unmask = ssb_gpio_irq_chipco_unmask,
124};
125
126static irqreturn_t ssb_gpio_irq_chipco_handler(int irq, void *dev_id)
127{
128 struct ssb_bus *bus = dev_id;
129 struct ssb_chipcommon *chipco = &bus->chipco;
130 u32 val = chipco_read32(chipco, SSB_CHIPCO_GPIOIN);
131 u32 mask = chipco_read32(chipco, SSB_CHIPCO_GPIOIRQ);
132 u32 pol = chipco_read32(chipco, SSB_CHIPCO_GPIOPOL);
133 unsigned long irqs = (val ^ pol) & mask;
134 int gpio;
135
136 if (!irqs)
137 return IRQ_NONE;
138
139 for_each_set_bit(gpio, &irqs, bus->gpio.ngpio)
140 generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio));
141 ssb_chipco_gpio_polarity(chipco, irqs, val & irqs);
142
143 return IRQ_HANDLED;
144}
145
146static int ssb_gpio_irq_chipco_domain_init(struct ssb_bus *bus)
147{
148 struct ssb_chipcommon *chipco = &bus->chipco;
149 struct gpio_chip *chip = &bus->gpio;
150 int gpio, hwirq, err;
151
152 if (bus->bustype != SSB_BUSTYPE_SSB)
153 return 0;
154
155 bus->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
156 &irq_domain_simple_ops, chipco);
157 if (!bus->irq_domain) {
158 err = -ENODEV;
159 goto err_irq_domain;
160 }
161 for (gpio = 0; gpio < chip->ngpio; gpio++) {
162 int irq = irq_create_mapping(bus->irq_domain, gpio);
163
164 irq_set_chip_data(irq, bus);
165 irq_set_chip_and_handler(irq, &ssb_gpio_irq_chipco_chip,
166 handle_simple_irq);
167 }
168
169 hwirq = ssb_mips_irq(bus->chipco.dev) + 2;
170 err = request_irq(hwirq, ssb_gpio_irq_chipco_handler, IRQF_SHARED,
171 "gpio", bus);
172 if (err)
173 goto err_req_irq;
174
175 ssb_chipco_gpio_intmask(&bus->chipco, ~0, 0);
176 chipco_set32(chipco, SSB_CHIPCO_IRQMASK, SSB_CHIPCO_IRQ_GPIO);
177
178 return 0;
179
180err_req_irq:
181 for (gpio = 0; gpio < chip->ngpio; gpio++) {
182 int irq = irq_find_mapping(bus->irq_domain, gpio);
183
184 irq_dispose_mapping(irq);
185 }
186 irq_domain_remove(bus->irq_domain);
187err_irq_domain:
188 return err;
189}
190
191static void ssb_gpio_irq_chipco_domain_exit(struct ssb_bus *bus)
192{
193 struct ssb_chipcommon *chipco = &bus->chipco;
194 struct gpio_chip *chip = &bus->gpio;
195 int gpio;
196
197 if (bus->bustype != SSB_BUSTYPE_SSB)
198 return;
199
200 chipco_mask32(chipco, SSB_CHIPCO_IRQMASK, ~SSB_CHIPCO_IRQ_GPIO);
201 free_irq(ssb_mips_irq(bus->chipco.dev) + 2, chipco);
202 for (gpio = 0; gpio < chip->ngpio; gpio++) {
203 int irq = irq_find_mapping(bus->irq_domain, gpio);
204
205 irq_dispose_mapping(irq);
206 }
207 irq_domain_remove(bus->irq_domain);
208}
209#else
210static int ssb_gpio_irq_chipco_domain_init(struct ssb_bus *bus)
211{
212 return 0;
85} 213}
86 214
215static void ssb_gpio_irq_chipco_domain_exit(struct ssb_bus *bus)
216{
217}
218#endif
219
87static int ssb_gpio_chipco_init(struct ssb_bus *bus) 220static int ssb_gpio_chipco_init(struct ssb_bus *bus)
88{ 221{
89 struct gpio_chip *chip = &bus->gpio; 222 struct gpio_chip *chip = &bus->gpio;
223 int err;
90 224
91 chip->label = "ssb_chipco_gpio"; 225 chip->label = "ssb_chipco_gpio";
92 chip->owner = THIS_MODULE; 226 chip->owner = THIS_MODULE;
@@ -96,7 +230,9 @@ static int ssb_gpio_chipco_init(struct ssb_bus *bus)
96 chip->set = ssb_gpio_chipco_set_value; 230 chip->set = ssb_gpio_chipco_set_value;
97 chip->direction_input = ssb_gpio_chipco_direction_input; 231 chip->direction_input = ssb_gpio_chipco_direction_input;
98 chip->direction_output = ssb_gpio_chipco_direction_output; 232 chip->direction_output = ssb_gpio_chipco_direction_output;
99 chip->to_irq = ssb_gpio_chipco_to_irq; 233#if IS_ENABLED(CONFIG_SSB_EMBEDDED)
234 chip->to_irq = ssb_gpio_to_irq;
235#endif
100 chip->ngpio = 16; 236 chip->ngpio = 16;
101 /* There is just one SoC in one device and its GPIO addresses should be 237 /* There is just one SoC in one device and its GPIO addresses should be
102 * deterministic to address them more easily. The other buses could get 238 * deterministic to address them more easily. The other buses could get
@@ -106,9 +242,23 @@ static int ssb_gpio_chipco_init(struct ssb_bus *bus)
106 else 242 else
107 chip->base = -1; 243 chip->base = -1;
108 244
109 return gpiochip_add(chip); 245 err = ssb_gpio_irq_chipco_domain_init(bus);
246 if (err)
247 return err;
248
249 err = gpiochip_add(chip);
250 if (err) {
251 ssb_gpio_irq_chipco_domain_exit(bus);
252 return err;
253 }
254
255 return 0;
110} 256}
111 257
258/**************************************************
259 * EXTIF
260 **************************************************/
261
112#ifdef CONFIG_SSB_DRIVER_EXTIF 262#ifdef CONFIG_SSB_DRIVER_EXTIF
113 263
114static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned gpio) 264static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned gpio)
@@ -145,19 +295,127 @@ static int ssb_gpio_extif_direction_output(struct gpio_chip *chip,
145 return 0; 295 return 0;
146} 296}
147 297
148static int ssb_gpio_extif_to_irq(struct gpio_chip *chip, unsigned gpio) 298#if IS_ENABLED(CONFIG_SSB_EMBEDDED)
299static void ssb_gpio_irq_extif_mask(struct irq_data *d)
149{ 300{
150 struct ssb_bus *bus = ssb_gpio_get_bus(chip); 301 struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
302 int gpio = irqd_to_hwirq(d);
151 303
152 if (bus->bustype == SSB_BUSTYPE_SSB) 304 ssb_extif_gpio_intmask(&bus->extif, BIT(gpio), 0);
153 return ssb_mips_irq(bus->extif.dev) + 2; 305}
154 else 306
155 return -EINVAL; 307static void ssb_gpio_irq_extif_unmask(struct irq_data *d)
308{
309 struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
310 int gpio = irqd_to_hwirq(d);
311 u32 val = ssb_extif_gpio_in(&bus->extif, BIT(gpio));
312
313 ssb_extif_gpio_polarity(&bus->extif, BIT(gpio), val);
314 ssb_extif_gpio_intmask(&bus->extif, BIT(gpio), BIT(gpio));
315}
316
317static struct irq_chip ssb_gpio_irq_extif_chip = {
318 .name = "SSB-GPIO-EXTIF",
319 .irq_mask = ssb_gpio_irq_extif_mask,
320 .irq_unmask = ssb_gpio_irq_extif_unmask,
321};
322
323static irqreturn_t ssb_gpio_irq_extif_handler(int irq, void *dev_id)
324{
325 struct ssb_bus *bus = dev_id;
326 struct ssb_extif *extif = &bus->extif;
327 u32 val = ssb_read32(extif->dev, SSB_EXTIF_GPIO_IN);
328 u32 mask = ssb_read32(extif->dev, SSB_EXTIF_GPIO_INTMASK);
329 u32 pol = ssb_read32(extif->dev, SSB_EXTIF_GPIO_INTPOL);
330 unsigned long irqs = (val ^ pol) & mask;
331 int gpio;
332
333 if (!irqs)
334 return IRQ_NONE;
335
336 for_each_set_bit(gpio, &irqs, bus->gpio.ngpio)
337 generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio));
338 ssb_extif_gpio_polarity(extif, irqs, val & irqs);
339
340 return IRQ_HANDLED;
341}
342
343static int ssb_gpio_irq_extif_domain_init(struct ssb_bus *bus)
344{
345 struct ssb_extif *extif = &bus->extif;
346 struct gpio_chip *chip = &bus->gpio;
347 int gpio, hwirq, err;
348
349 if (bus->bustype != SSB_BUSTYPE_SSB)
350 return 0;
351
352 bus->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
353 &irq_domain_simple_ops, extif);
354 if (!bus->irq_domain) {
355 err = -ENODEV;
356 goto err_irq_domain;
357 }
358 for (gpio = 0; gpio < chip->ngpio; gpio++) {
359 int irq = irq_create_mapping(bus->irq_domain, gpio);
360
361 irq_set_chip_data(irq, bus);
362 irq_set_chip_and_handler(irq, &ssb_gpio_irq_extif_chip,
363 handle_simple_irq);
364 }
365
366 hwirq = ssb_mips_irq(bus->extif.dev) + 2;
367 err = request_irq(hwirq, ssb_gpio_irq_extif_handler, IRQF_SHARED,
368 "gpio", bus);
369 if (err)
370 goto err_req_irq;
371
372 ssb_extif_gpio_intmask(&bus->extif, ~0, 0);
373
374 return 0;
375
376err_req_irq:
377 for (gpio = 0; gpio < chip->ngpio; gpio++) {
378 int irq = irq_find_mapping(bus->irq_domain, gpio);
379
380 irq_dispose_mapping(irq);
381 }
382 irq_domain_remove(bus->irq_domain);
383err_irq_domain:
384 return err;
385}
386
387static void ssb_gpio_irq_extif_domain_exit(struct ssb_bus *bus)
388{
389 struct ssb_extif *extif = &bus->extif;
390 struct gpio_chip *chip = &bus->gpio;
391 int gpio;
392
393 if (bus->bustype != SSB_BUSTYPE_SSB)
394 return;
395
396 free_irq(ssb_mips_irq(bus->extif.dev) + 2, extif);
397 for (gpio = 0; gpio < chip->ngpio; gpio++) {
398 int irq = irq_find_mapping(bus->irq_domain, gpio);
399
400 irq_dispose_mapping(irq);
401 }
402 irq_domain_remove(bus->irq_domain);
156} 403}
404#else
405static int ssb_gpio_irq_extif_domain_init(struct ssb_bus *bus)
406{
407 return 0;
408}
409
410static void ssb_gpio_irq_extif_domain_exit(struct ssb_bus *bus)
411{
412}
413#endif
157 414
158static int ssb_gpio_extif_init(struct ssb_bus *bus) 415static int ssb_gpio_extif_init(struct ssb_bus *bus)
159{ 416{
160 struct gpio_chip *chip = &bus->gpio; 417 struct gpio_chip *chip = &bus->gpio;
418 int err;
161 419
162 chip->label = "ssb_extif_gpio"; 420 chip->label = "ssb_extif_gpio";
163 chip->owner = THIS_MODULE; 421 chip->owner = THIS_MODULE;
@@ -165,7 +423,9 @@ static int ssb_gpio_extif_init(struct ssb_bus *bus)
165 chip->set = ssb_gpio_extif_set_value; 423 chip->set = ssb_gpio_extif_set_value;
166 chip->direction_input = ssb_gpio_extif_direction_input; 424 chip->direction_input = ssb_gpio_extif_direction_input;
167 chip->direction_output = ssb_gpio_extif_direction_output; 425 chip->direction_output = ssb_gpio_extif_direction_output;
168 chip->to_irq = ssb_gpio_extif_to_irq; 426#if IS_ENABLED(CONFIG_SSB_EMBEDDED)
427 chip->to_irq = ssb_gpio_to_irq;
428#endif
169 chip->ngpio = 5; 429 chip->ngpio = 5;
170 /* There is just one SoC in one device and its GPIO addresses should be 430 /* There is just one SoC in one device and its GPIO addresses should be
171 * deterministic to address them more easily. The other buses could get 431 * deterministic to address them more easily. The other buses could get
@@ -175,7 +435,17 @@ static int ssb_gpio_extif_init(struct ssb_bus *bus)
175 else 435 else
176 chip->base = -1; 436 chip->base = -1;
177 437
178 return gpiochip_add(chip); 438 err = ssb_gpio_irq_extif_domain_init(bus);
439 if (err)
440 return err;
441
442 err = gpiochip_add(chip);
443 if (err) {
444 ssb_gpio_irq_extif_domain_exit(bus);
445 return err;
446 }
447
448 return 0;
179} 449}
180 450
181#else 451#else
@@ -185,6 +455,10 @@ static int ssb_gpio_extif_init(struct ssb_bus *bus)
185} 455}
186#endif 456#endif
187 457
458/**************************************************
459 * Init
460 **************************************************/
461
188int ssb_gpio_init(struct ssb_bus *bus) 462int ssb_gpio_init(struct ssb_bus *bus)
189{ 463{
190 if (ssb_chipco_available(&bus->chipco)) 464 if (ssb_chipco_available(&bus->chipco))
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 32a811d11c25..2fead3820849 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -593,6 +593,13 @@ static int ssb_attach_queued_buses(void)
593 ssb_pcicore_init(&bus->pcicore); 593 ssb_pcicore_init(&bus->pcicore);
594 if (bus->bustype == SSB_BUSTYPE_SSB) 594 if (bus->bustype == SSB_BUSTYPE_SSB)
595 ssb_watchdog_register(bus); 595 ssb_watchdog_register(bus);
596
597 err = ssb_gpio_init(bus);
598 if (err == -ENOTSUPP)
599 ssb_dbg("GPIO driver not activated\n");
600 else if (err)
601 ssb_dbg("Error registering GPIO driver: %i\n", err);
602
596 ssb_bus_may_powerdown(bus); 603 ssb_bus_may_powerdown(bus);
597 604
598 err = ssb_devices_register(bus); 605 err = ssb_devices_register(bus);
@@ -830,11 +837,6 @@ static int ssb_bus_register(struct ssb_bus *bus,
830 ssb_chipcommon_init(&bus->chipco); 837 ssb_chipcommon_init(&bus->chipco);
831 ssb_extif_init(&bus->extif); 838 ssb_extif_init(&bus->extif);
832 ssb_mipscore_init(&bus->mipscore); 839 ssb_mipscore_init(&bus->mipscore);
833 err = ssb_gpio_init(bus);
834 if (err == -ENOTSUPP)
835 ssb_dbg("GPIO driver not activated\n");
836 else if (err)
837 ssb_dbg("Error registering GPIO driver: %i\n", err);
838 err = ssb_fetch_invariants(bus, get_invariants); 840 err = ssb_fetch_invariants(bus, get_invariants);
839 if (err) { 841 if (err) {
840 ssb_bus_may_powerdown(bus); 842 ssb_bus_may_powerdown(bus);