summaryrefslogtreecommitdiffstats
path: root/drivers/bcma
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2015-08-13 18:21:45 -0400
committerKalle Valo <kvalo@codeaurora.org>2015-08-18 02:08:47 -0400
commit74f4e0cc61080f63f28e8d519bdf437957e64217 (patch)
tree4c12a5b2cc3a09f240698c796abb17ca3002c5fb /drivers/bcma
parent1165dd900cc8de3addbc8bef7e6196b07799d25e (diff)
bcma: switch GPIO portions to use GPIOLIB_IRQCHIP
This switches the BCMA GPIO driver to use GPIOLIB_IRQCHIP to handle its interrupts instead of rolling its own copy of the irqdomain handling etc. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/bcma')
-rw-r--r--drivers/bcma/Kconfig2
-rw-r--r--drivers/bcma/driver_gpio.c92
2 files changed, 31 insertions, 63 deletions
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
index be5fffb6da24..023d448ed3fa 100644
--- a/drivers/bcma/Kconfig
+++ b/drivers/bcma/Kconfig
@@ -92,7 +92,7 @@ config BCMA_DRIVER_GMAC_CMN
92config BCMA_DRIVER_GPIO 92config BCMA_DRIVER_GPIO
93 bool "BCMA GPIO driver" 93 bool "BCMA GPIO driver"
94 depends on BCMA && GPIOLIB 94 depends on BCMA && GPIOLIB
95 select IRQ_DOMAIN if BCMA_HOST_SOC 95 select GPIOLIB_IRQCHIP if BCMA_HOST_SOC
96 help 96 help
97 Driver to provide access to the GPIO pins of the bcma bus. 97 Driver to provide access to the GPIO pins of the bcma bus.
98 98
diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c
index 5f6018e7cd4c..504899a72966 100644
--- a/drivers/bcma/driver_gpio.c
+++ b/drivers/bcma/driver_gpio.c
@@ -8,10 +8,8 @@
8 * Licensed under the GNU/GPL. See COPYING for details. 8 * Licensed under the GNU/GPL. See COPYING for details.
9 */ 9 */
10 10
11#include <linux/gpio.h> 11#include <linux/gpio/driver.h>
12#include <linux/irq.h>
13#include <linux/interrupt.h> 12#include <linux/interrupt.h>
14#include <linux/irqdomain.h>
15#include <linux/export.h> 13#include <linux/export.h>
16#include <linux/bcma/bcma.h> 14#include <linux/bcma/bcma.h>
17 15
@@ -79,19 +77,11 @@ static void bcma_gpio_free(struct gpio_chip *chip, unsigned gpio)
79} 77}
80 78
81#if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X) 79#if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X)
82static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
83{
84 struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
85
86 if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
87 return irq_find_mapping(cc->irq_domain, gpio);
88 else
89 return -EINVAL;
90}
91 80
92static void bcma_gpio_irq_unmask(struct irq_data *d) 81static void bcma_gpio_irq_unmask(struct irq_data *d)
93{ 82{
94 struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d); 83 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
84 struct bcma_drv_cc *cc = bcma_gpio_get_cc(gc);
95 int gpio = irqd_to_hwirq(d); 85 int gpio = irqd_to_hwirq(d);
96 u32 val = bcma_chipco_gpio_in(cc, BIT(gpio)); 86 u32 val = bcma_chipco_gpio_in(cc, BIT(gpio));
97 87
@@ -101,7 +91,8 @@ static void bcma_gpio_irq_unmask(struct irq_data *d)
101 91
102static void bcma_gpio_irq_mask(struct irq_data *d) 92static void bcma_gpio_irq_mask(struct irq_data *d)
103{ 93{
104 struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d); 94 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
95 struct bcma_drv_cc *cc = bcma_gpio_get_cc(gc);
105 int gpio = irqd_to_hwirq(d); 96 int gpio = irqd_to_hwirq(d);
106 97
107 bcma_chipco_gpio_intmask(cc, BIT(gpio), 0); 98 bcma_chipco_gpio_intmask(cc, BIT(gpio), 0);
@@ -116,6 +107,7 @@ static struct irq_chip bcma_gpio_irq_chip = {
116static irqreturn_t bcma_gpio_irq_handler(int irq, void *dev_id) 107static irqreturn_t bcma_gpio_irq_handler(int irq, void *dev_id)
117{ 108{
118 struct bcma_drv_cc *cc = dev_id; 109 struct bcma_drv_cc *cc = dev_id;
110 struct gpio_chip *gc = &cc->gpio;
119 u32 val = bcma_cc_read32(cc, BCMA_CC_GPIOIN); 111 u32 val = bcma_cc_read32(cc, BCMA_CC_GPIOIN);
120 u32 mask = bcma_cc_read32(cc, BCMA_CC_GPIOIRQ); 112 u32 mask = bcma_cc_read32(cc, BCMA_CC_GPIOIRQ);
121 u32 pol = bcma_cc_read32(cc, BCMA_CC_GPIOPOL); 113 u32 pol = bcma_cc_read32(cc, BCMA_CC_GPIOPOL);
@@ -125,81 +117,58 @@ static irqreturn_t bcma_gpio_irq_handler(int irq, void *dev_id)
125 if (!irqs) 117 if (!irqs)
126 return IRQ_NONE; 118 return IRQ_NONE;
127 119
128 for_each_set_bit(gpio, &irqs, cc->gpio.ngpio) 120 for_each_set_bit(gpio, &irqs, gc->ngpio)
129 generic_handle_irq(bcma_gpio_to_irq(&cc->gpio, gpio)); 121 generic_handle_irq(irq_find_mapping(gc->irqdomain, gpio));
130 bcma_chipco_gpio_polarity(cc, irqs, val & irqs); 122 bcma_chipco_gpio_polarity(cc, irqs, val & irqs);
131 123
132 return IRQ_HANDLED; 124 return IRQ_HANDLED;
133} 125}
134 126
135static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc) 127static int bcma_gpio_irq_init(struct bcma_drv_cc *cc)
136{ 128{
137 struct gpio_chip *chip = &cc->gpio; 129 struct gpio_chip *chip = &cc->gpio;
138 int gpio, hwirq, err; 130 int hwirq, err;
139 131
140 if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC) 132 if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC)
141 return 0; 133 return 0;
142 134
143 cc->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
144 &irq_domain_simple_ops, cc);
145 if (!cc->irq_domain) {
146 err = -ENODEV;
147 goto err_irq_domain;
148 }
149 for (gpio = 0; gpio < chip->ngpio; gpio++) {
150 int irq = irq_create_mapping(cc->irq_domain, gpio);
151
152 irq_set_chip_data(irq, cc);
153 irq_set_chip_and_handler(irq, &bcma_gpio_irq_chip,
154 handle_simple_irq);
155 }
156
157 hwirq = bcma_core_irq(cc->core, 0); 135 hwirq = bcma_core_irq(cc->core, 0);
158 err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio", 136 err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio",
159 cc); 137 cc);
160 if (err) 138 if (err)
161 goto err_req_irq; 139 return err;
162 140
163 bcma_chipco_gpio_intmask(cc, ~0, 0); 141 bcma_chipco_gpio_intmask(cc, ~0, 0);
164 bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO); 142 bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO);
165 143
166 return 0; 144 err = gpiochip_irqchip_add(chip,
167 145 &bcma_gpio_irq_chip,
168err_req_irq: 146 0,
169 for (gpio = 0; gpio < chip->ngpio; gpio++) { 147 handle_simple_irq,
170 int irq = irq_find_mapping(cc->irq_domain, gpio); 148 IRQ_TYPE_NONE);
171 149 if (err) {
172 irq_dispose_mapping(irq); 150 free_irq(hwirq, cc);
151 return err;
173 } 152 }
174 irq_domain_remove(cc->irq_domain); 153
175err_irq_domain: 154 return 0;
176 return err;
177} 155}
178 156
179static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc) 157static void bcma_gpio_irq_exit(struct bcma_drv_cc *cc)
180{ 158{
181 struct gpio_chip *chip = &cc->gpio;
182 int gpio;
183
184 if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC) 159 if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC)
185 return; 160 return;
186 161
187 bcma_cc_mask32(cc, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO); 162 bcma_cc_mask32(cc, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO);
188 free_irq(bcma_core_irq(cc->core, 0), cc); 163 free_irq(bcma_core_irq(cc->core, 0), cc);
189 for (gpio = 0; gpio < chip->ngpio; gpio++) {
190 int irq = irq_find_mapping(cc->irq_domain, gpio);
191
192 irq_dispose_mapping(irq);
193 }
194 irq_domain_remove(cc->irq_domain);
195} 164}
196#else 165#else
197static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc) 166static int bcma_gpio_irq_init(struct bcma_drv_cc *cc)
198{ 167{
199 return 0; 168 return 0;
200} 169}
201 170
202static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc) 171static void bcma_gpio_irq_exit(struct bcma_drv_cc *cc)
203{ 172{
204} 173}
205#endif 174#endif
@@ -218,9 +187,8 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
218 chip->set = bcma_gpio_set_value; 187 chip->set = bcma_gpio_set_value;
219 chip->direction_input = bcma_gpio_direction_input; 188 chip->direction_input = bcma_gpio_direction_input;
220 chip->direction_output = bcma_gpio_direction_output; 189 chip->direction_output = bcma_gpio_direction_output;
221#if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X) 190 chip->owner = THIS_MODULE;
222 chip->to_irq = bcma_gpio_to_irq; 191 chip->dev = bcma_bus_get_host_dev(bus);
223#endif
224#if IS_BUILTIN(CONFIG_OF) 192#if IS_BUILTIN(CONFIG_OF)
225 if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC) 193 if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
226 chip->of_node = cc->core->dev.of_node; 194 chip->of_node = cc->core->dev.of_node;
@@ -248,13 +216,13 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
248 else 216 else
249 chip->base = -1; 217 chip->base = -1;
250 218
251 err = bcma_gpio_irq_domain_init(cc); 219 err = gpiochip_add(chip);
252 if (err) 220 if (err)
253 return err; 221 return err;
254 222
255 err = gpiochip_add(chip); 223 err = bcma_gpio_irq_init(cc);
256 if (err) { 224 if (err) {
257 bcma_gpio_irq_domain_exit(cc); 225 gpiochip_remove(chip);
258 return err; 226 return err;
259 } 227 }
260 228
@@ -263,7 +231,7 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
263 231
264int bcma_gpio_unregister(struct bcma_drv_cc *cc) 232int bcma_gpio_unregister(struct bcma_drv_cc *cc)
265{ 233{
266 bcma_gpio_irq_domain_exit(cc); 234 bcma_gpio_irq_exit(cc);
267 gpiochip_remove(&cc->gpio); 235 gpiochip_remove(&cc->gpio);
268 return 0; 236 return 0;
269} 237}