aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2014-03-25 05:42:35 -0400
committerLinus Walleij <linus.walleij@linaro.org>2014-03-26 05:31:33 -0400
commit8d5b24bd30c23930e666813ea0adc4672ea58c62 (patch)
tree1f0d7d96bd8c4a81719ca514e8c8301f7706a423
parent1425052097b53de841e064dc190a9009480c208c (diff)
gpio: pl061: convert driver to use gpiolib irqchip
This converts the PL061 driver to register its chained irq handler and irqchip using the helpers in the gpiolib core. Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/gpio/Kconfig1
-rw-r--r--drivers/gpio/gpio-pl061.c80
2 files changed, 19 insertions, 62 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 51c782532687..92d8e9a064b4 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -247,6 +247,7 @@ config GPIO_PL061
247 bool "PrimeCell PL061 GPIO support" 247 bool "PrimeCell PL061 GPIO support"
248 depends on ARM_AMBA 248 depends on ARM_AMBA
249 select IRQ_DOMAIN 249 select IRQ_DOMAIN
250 select GPIOLIB_IRQCHIP
250 help 251 help
251 Say yes here to support the PrimeCell PL061 GPIO device 252 Say yes here to support the PrimeCell PL061 GPIO device
252 253
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index d2a0ad5fc752..b0f475243cef 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -15,7 +15,6 @@
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/ioport.h> 16#include <linux/ioport.h>
17#include <linux/irq.h> 17#include <linux/irq.h>
18#include <linux/irqdomain.h>
19#include <linux/irqchip/chained_irq.h> 18#include <linux/irqchip/chained_irq.h>
20#include <linux/bitops.h> 19#include <linux/bitops.h>
21#include <linux/workqueue.h> 20#include <linux/workqueue.h>
@@ -53,7 +52,6 @@ struct pl061_gpio {
53 spinlock_t lock; 52 spinlock_t lock;
54 53
55 void __iomem *base; 54 void __iomem *base;
56 struct irq_domain *domain;
57 struct gpio_chip gc; 55 struct gpio_chip gc;
58 56
59#ifdef CONFIG_PM 57#ifdef CONFIG_PM
@@ -137,16 +135,10 @@ static void pl061_set_value(struct gpio_chip *gc, unsigned offset, int value)
137 writeb(!!value << offset, chip->base + (1 << (offset + 2))); 135 writeb(!!value << offset, chip->base + (1 << (offset + 2)));
138} 136}
139 137
140static int pl061_to_irq(struct gpio_chip *gc, unsigned offset)
141{
142 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
143
144 return irq_create_mapping(chip->domain, offset);
145}
146
147static int pl061_irq_type(struct irq_data *d, unsigned trigger) 138static int pl061_irq_type(struct irq_data *d, unsigned trigger)
148{ 139{
149 struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); 140 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
141 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
150 int offset = irqd_to_hwirq(d); 142 int offset = irqd_to_hwirq(d);
151 unsigned long flags; 143 unsigned long flags;
152 u8 gpiois, gpioibe, gpioiev; 144 u8 gpiois, gpioibe, gpioiev;
@@ -194,7 +186,8 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
194{ 186{
195 unsigned long pending; 187 unsigned long pending;
196 int offset; 188 int offset;
197 struct pl061_gpio *chip = irq_desc_get_handler_data(desc); 189 struct gpio_chip *gc = irq_desc_get_handler_data(desc);
190 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
198 struct irq_chip *irqchip = irq_desc_get_chip(desc); 191 struct irq_chip *irqchip = irq_desc_get_chip(desc);
199 192
200 chained_irq_enter(irqchip, desc); 193 chained_irq_enter(irqchip, desc);
@@ -203,7 +196,8 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
203 writeb(pending, chip->base + GPIOIC); 196 writeb(pending, chip->base + GPIOIC);
204 if (pending) { 197 if (pending) {
205 for_each_set_bit(offset, &pending, PL061_GPIO_NR) 198 for_each_set_bit(offset, &pending, PL061_GPIO_NR)
206 generic_handle_irq(pl061_to_irq(&chip->gc, offset)); 199 generic_handle_irq(irq_find_mapping(gc->irqdomain,
200 offset));
207 } 201 }
208 202
209 chained_irq_exit(irqchip, desc); 203 chained_irq_exit(irqchip, desc);
@@ -211,7 +205,8 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
211 205
212static void pl061_irq_mask(struct irq_data *d) 206static void pl061_irq_mask(struct irq_data *d)
213{ 207{
214 struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); 208 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
209 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
215 u8 mask = 1 << (irqd_to_hwirq(d) % PL061_GPIO_NR); 210 u8 mask = 1 << (irqd_to_hwirq(d) % PL061_GPIO_NR);
216 u8 gpioie; 211 u8 gpioie;
217 212
@@ -223,7 +218,8 @@ static void pl061_irq_mask(struct irq_data *d)
223 218
224static void pl061_irq_unmask(struct irq_data *d) 219static void pl061_irq_unmask(struct irq_data *d)
225{ 220{
226 struct pl061_gpio *chip = irq_data_get_irq_chip_data(d); 221 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
222 struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
227 u8 mask = 1 << (irqd_to_hwirq(d) % PL061_GPIO_NR); 223 u8 mask = 1 << (irqd_to_hwirq(d) % PL061_GPIO_NR);
228 u8 gpioie; 224 u8 gpioie;
229 225
@@ -233,50 +229,11 @@ static void pl061_irq_unmask(struct irq_data *d)
233 spin_unlock(&chip->lock); 229 spin_unlock(&chip->lock);
234} 230}
235 231
236static int pl061_irq_reqres(struct irq_data *d)
237{
238 struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
239
240 if (gpio_lock_as_irq(&chip->gc, irqd_to_hwirq(d))) {
241 dev_err(chip->gc.dev,
242 "unable to lock HW IRQ %lu for IRQ\n",
243 irqd_to_hwirq(d));
244 return -EINVAL;
245 }
246 return 0;
247}
248
249static void pl061_irq_relres(struct irq_data *d)
250{
251 struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
252
253 gpio_unlock_as_irq(&chip->gc, irqd_to_hwirq(d));
254}
255
256static struct irq_chip pl061_irqchip = { 232static struct irq_chip pl061_irqchip = {
257 .name = "pl061", 233 .name = "pl061",
258 .irq_mask = pl061_irq_mask, 234 .irq_mask = pl061_irq_mask,
259 .irq_unmask = pl061_irq_unmask, 235 .irq_unmask = pl061_irq_unmask,
260 .irq_set_type = pl061_irq_type, 236 .irq_set_type = pl061_irq_type,
261 .irq_request_resources = pl061_irq_reqres,
262 .irq_release_resources = pl061_irq_relres,
263};
264
265static int pl061_irq_map(struct irq_domain *d, unsigned int irq,
266 irq_hw_number_t hwirq)
267{
268 struct pl061_gpio *chip = d->host_data;
269
270 irq_set_chip_and_handler(irq, &pl061_irqchip, handle_simple_irq);
271 irq_set_chip_data(irq, chip);
272 irq_set_irq_type(irq, IRQ_TYPE_NONE);
273
274 return 0;
275}
276
277static const struct irq_domain_ops pl061_domain_ops = {
278 .map = pl061_irq_map,
279 .xlate = irq_domain_xlate_twocell,
280}; 237};
281 238
282static int pl061_probe(struct amba_device *adev, const struct amba_id *id) 239static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
@@ -314,7 +271,6 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
314 chip->gc.direction_output = pl061_direction_output; 271 chip->gc.direction_output = pl061_direction_output;
315 chip->gc.get = pl061_get_value; 272 chip->gc.get = pl061_get_value;
316 chip->gc.set = pl061_set_value; 273 chip->gc.set = pl061_set_value;
317 chip->gc.to_irq = pl061_to_irq;
318 chip->gc.ngpio = PL061_GPIO_NR; 274 chip->gc.ngpio = PL061_GPIO_NR;
319 chip->gc.label = dev_name(dev); 275 chip->gc.label = dev_name(dev);
320 chip->gc.dev = dev; 276 chip->gc.dev = dev;
@@ -334,15 +290,15 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
334 return -ENODEV; 290 return -ENODEV;
335 } 291 }
336 292
337 irq_set_chained_handler(irq, pl061_irq_handler); 293 ret = gpiochip_irqchip_add(&chip->gc, &pl061_irqchip,
338 irq_set_handler_data(irq, chip); 294 irq_base, handle_simple_irq,
339 295 IRQ_TYPE_NONE);
340 chip->domain = irq_domain_add_simple(adev->dev.of_node, PL061_GPIO_NR, 296 if (ret) {
341 irq_base, &pl061_domain_ops, chip); 297 dev_info(&adev->dev, "could not add irqchip\n");
342 if (!chip->domain) { 298 return ret;
343 dev_err(&adev->dev, "no irq domain\n");
344 return -ENODEV;
345 } 299 }
300 gpiochip_set_chained_irqchip(&chip->gc, &pl061_irqchip,
301 irq, pl061_irq_handler);
346 302
347 for (i = 0; i < PL061_GPIO_NR; i++) { 303 for (i = 0; i < PL061_GPIO_NR; i++) {
348 if (pdata) { 304 if (pdata) {