aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2014-05-29 10:55:55 -0400
committerLinus Walleij <linus.walleij@linaro.org>2014-06-19 03:31:16 -0400
commit3f7dbfd8eea9a2989485886029b1bd2a6b441f3e (patch)
tree8c19f6747c0299edc94622e023cf8a855d9933aa /drivers/gpio
parentfe44e70db0544e24cd1d00fc594b6e5b0afd333b (diff)
gpio: intel-mid: switch to using gpiolib irqchip helpers
This switches the Intel MID GPIO driver over to using the gpiolib irqchip helpers in the gpiolib core. Cc: xinhui.pan <xinhuiX.pan@intel.com> Acked-by: David Cohen <david.a.cohen@linux.intel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-intel-mid.c86
1 files changed, 25 insertions, 61 deletions
diff --git a/drivers/gpio/gpio-intel-mid.c b/drivers/gpio/gpio-intel-mid.c
index 118a6bf455d9..aa28c65eb6b4 100644
--- a/drivers/gpio/gpio-intel-mid.c
+++ b/drivers/gpio/gpio-intel-mid.c
@@ -28,12 +28,10 @@
28#include <linux/stddef.h> 28#include <linux/stddef.h>
29#include <linux/interrupt.h> 29#include <linux/interrupt.h>
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/irq.h>
32#include <linux/io.h> 31#include <linux/io.h>
33#include <linux/gpio.h> 32#include <linux/gpio/driver.h>
34#include <linux/slab.h> 33#include <linux/slab.h>
35#include <linux/pm_runtime.h> 34#include <linux/pm_runtime.h>
36#include <linux/irqdomain.h>
37 35
38#define INTEL_MID_IRQ_TYPE_EDGE (1 << 0) 36#define INTEL_MID_IRQ_TYPE_EDGE (1 << 0)
39#define INTEL_MID_IRQ_TYPE_LEVEL (1 << 1) 37#define INTEL_MID_IRQ_TYPE_LEVEL (1 << 1)
@@ -78,10 +76,12 @@ struct intel_mid_gpio {
78 void __iomem *reg_base; 76 void __iomem *reg_base;
79 spinlock_t lock; 77 spinlock_t lock;
80 struct pci_dev *pdev; 78 struct pci_dev *pdev;
81 struct irq_domain *domain;
82}; 79};
83 80
84#define to_intel_gpio_priv(chip) container_of(chip, struct intel_mid_gpio, chip) 81static inline struct intel_mid_gpio *to_intel_gpio_priv(struct gpio_chip *gc)
82{
83 return container_of(gc, struct intel_mid_gpio, chip);
84}
85 85
86static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset, 86static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset,
87 enum GPIO_REG reg_type) 87 enum GPIO_REG reg_type)
@@ -182,15 +182,10 @@ static int intel_gpio_direction_output(struct gpio_chip *chip,
182 return 0; 182 return 0;
183} 183}
184 184
185static int intel_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
186{
187 struct intel_mid_gpio *priv = to_intel_gpio_priv(chip);
188 return irq_create_mapping(priv->domain, offset);
189}
190
191static int intel_mid_irq_type(struct irq_data *d, unsigned type) 185static int intel_mid_irq_type(struct irq_data *d, unsigned type)
192{ 186{
193 struct intel_mid_gpio *priv = irq_data_get_irq_chip_data(d); 187 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
188 struct intel_mid_gpio *priv = to_intel_gpio_priv(gc);
194 u32 gpio = irqd_to_hwirq(d); 189 u32 gpio = irqd_to_hwirq(d);
195 unsigned long flags; 190 unsigned long flags;
196 u32 value; 191 u32 value;
@@ -231,33 +226,11 @@ static void intel_mid_irq_mask(struct irq_data *d)
231{ 226{
232} 227}
233 228
234static int intel_mid_irq_reqres(struct irq_data *d)
235{
236 struct intel_mid_gpio *priv = irq_data_get_irq_chip_data(d);
237
238 if (gpio_lock_as_irq(&priv->chip, irqd_to_hwirq(d))) {
239 dev_err(priv->chip.dev,
240 "unable to lock HW IRQ %lu for IRQ\n",
241 irqd_to_hwirq(d));
242 return -EINVAL;
243 }
244 return 0;
245}
246
247static void intel_mid_irq_relres(struct irq_data *d)
248{
249 struct intel_mid_gpio *priv = irq_data_get_irq_chip_data(d);
250
251 gpio_unlock_as_irq(&priv->chip, irqd_to_hwirq(d));
252}
253
254static struct irq_chip intel_mid_irqchip = { 229static struct irq_chip intel_mid_irqchip = {
255 .name = "INTEL_MID-GPIO", 230 .name = "INTEL_MID-GPIO",
256 .irq_mask = intel_mid_irq_mask, 231 .irq_mask = intel_mid_irq_mask,
257 .irq_unmask = intel_mid_irq_unmask, 232 .irq_unmask = intel_mid_irq_unmask,
258 .irq_set_type = intel_mid_irq_type, 233 .irq_set_type = intel_mid_irq_type,
259 .irq_request_resources = intel_mid_irq_reqres,
260 .irq_release_resources = intel_mid_irq_relres,
261}; 234};
262 235
263static const struct intel_mid_gpio_ddata gpio_lincroft = { 236static const struct intel_mid_gpio_ddata gpio_lincroft = {
@@ -330,8 +303,9 @@ MODULE_DEVICE_TABLE(pci, intel_gpio_ids);
330 303
331static void intel_mid_irq_handler(unsigned irq, struct irq_desc *desc) 304static void intel_mid_irq_handler(unsigned irq, struct irq_desc *desc)
332{ 305{
306 struct gpio_chip *gc = irq_desc_get_handler_data(desc);
307 struct intel_mid_gpio *priv = to_intel_gpio_priv(gc);
333 struct irq_data *data = irq_desc_get_irq_data(desc); 308 struct irq_data *data = irq_desc_get_irq_data(desc);
334 struct intel_mid_gpio *priv = irq_data_get_irq_handler_data(data);
335 struct irq_chip *chip = irq_data_get_irq_chip(data); 309 struct irq_chip *chip = irq_data_get_irq_chip(data);
336 u32 base, gpio, mask; 310 u32 base, gpio, mask;
337 unsigned long pending; 311 unsigned long pending;
@@ -345,7 +319,7 @@ static void intel_mid_irq_handler(unsigned irq, struct irq_desc *desc)
345 mask = BIT(gpio); 319 mask = BIT(gpio);
346 /* Clear before handling so we can't lose an edge */ 320 /* Clear before handling so we can't lose an edge */
347 writel(mask, gedr); 321 writel(mask, gedr);
348 generic_handle_irq(irq_find_mapping(priv->domain, 322 generic_handle_irq(irq_find_mapping(gc->irqdomain,
349 base + gpio)); 323 base + gpio));
350 } 324 }
351 } 325 }
@@ -371,23 +345,6 @@ static void intel_mid_irq_init_hw(struct intel_mid_gpio *priv)
371 } 345 }
372} 346}
373 347
374static int intel_gpio_irq_map(struct irq_domain *d, unsigned int irq,
375 irq_hw_number_t hwirq)
376{
377 struct intel_mid_gpio *priv = d->host_data;
378
379 irq_set_chip_and_handler(irq, &intel_mid_irqchip, handle_simple_irq);
380 irq_set_chip_data(irq, priv);
381 irq_set_irq_type(irq, IRQ_TYPE_NONE);
382
383 return 0;
384}
385
386static const struct irq_domain_ops intel_gpio_irq_ops = {
387 .map = intel_gpio_irq_map,
388 .xlate = irq_domain_xlate_twocell,
389};
390
391static int intel_gpio_runtime_idle(struct device *dev) 348static int intel_gpio_runtime_idle(struct device *dev)
392{ 349{
393 int err = pm_schedule_suspend(dev, 500); 350 int err = pm_schedule_suspend(dev, 500);
@@ -441,7 +398,6 @@ static int intel_gpio_probe(struct pci_dev *pdev,
441 priv->chip.direction_output = intel_gpio_direction_output; 398 priv->chip.direction_output = intel_gpio_direction_output;
442 priv->chip.get = intel_gpio_get; 399 priv->chip.get = intel_gpio_get;
443 priv->chip.set = intel_gpio_set; 400 priv->chip.set = intel_gpio_set;
444 priv->chip.to_irq = intel_gpio_to_irq;
445 priv->chip.base = gpio_base; 401 priv->chip.base = gpio_base;
446 priv->chip.ngpio = ddata->ngpio; 402 priv->chip.ngpio = ddata->ngpio;
447 priv->chip.can_sleep = false; 403 priv->chip.can_sleep = false;
@@ -449,11 +405,6 @@ static int intel_gpio_probe(struct pci_dev *pdev,
449 405
450 spin_lock_init(&priv->lock); 406 spin_lock_init(&priv->lock);
451 407
452 priv->domain = irq_domain_add_simple(pdev->dev.of_node, ddata->ngpio,
453 irq_base, &intel_gpio_irq_ops, priv);
454 if (!priv->domain)
455 return -ENOMEM;
456
457 pci_set_drvdata(pdev, priv); 408 pci_set_drvdata(pdev, priv);
458 retval = gpiochip_add(&priv->chip); 409 retval = gpiochip_add(&priv->chip);
459 if (retval) { 410 if (retval) {
@@ -461,10 +412,23 @@ static int intel_gpio_probe(struct pci_dev *pdev,
461 return retval; 412 return retval;
462 } 413 }
463 414
415 retval = gpiochip_irqchip_add(&priv->chip,
416 &intel_mid_irqchip,
417 irq_base,
418 handle_simple_irq,
419 IRQ_TYPE_NONE);
420 if (retval) {
421 dev_err(&pdev->dev,
422 "could not connect irqchip to gpiochip\n");
423 return retval;
424 }
425
464 intel_mid_irq_init_hw(priv); 426 intel_mid_irq_init_hw(priv);
465 427
466 irq_set_handler_data(pdev->irq, priv); 428 gpiochip_set_chained_irqchip(&priv->chip,
467 irq_set_chained_handler(pdev->irq, intel_mid_irq_handler); 429 &intel_mid_irqchip,
430 pdev->irq,
431 intel_mid_irq_handler);
468 432
469 pm_runtime_put_noidle(&pdev->dev); 433 pm_runtime_put_noidle(&pdev->dev);
470 pm_runtime_allow(&pdev->dev); 434 pm_runtime_allow(&pdev->dev);