diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-08 18:00:35 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-08 18:00:35 -0700 |
commit | 06b49ea43c0cdd22625883e555e45e66ef29e201 (patch) | |
tree | 9c72c88541e2bec5a95354504708a066fd8e50aa /drivers/gpio/gpio-lynxpoint.c | |
parent | 664fb23070ae66a023250a83870a5bae7cd0efeb (diff) | |
parent | bdc6e95e1273b5cef01590273c1a240c53ceeea0 (diff) |
Merge tag 'gpio-v3.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio
Pull GPIO update from Linus Walleij:
"This is the bulk of GPIO changes for the v3.17 development cycle, and
this time we got a lot of action going on and it will continue:
- The core GPIO library implementation has been split up in three
different files:
- gpiolib.c for the latest and greatest and shiny GPIO library code
using GPIO descriptors only
- gpiolib-legacy.c for the old integer number space API that we are
phasing out gradually
- gpiolib-sysfs.c for the sysfs interface that we are not entirely
happy with, but has to live on for ABI compatibility
- Add a flags argument to *gpiod_get* functions, with some
backward-compatibility macros to ease transitions. We should have
had the flags there from the beginning it seems, now we need to
clean up the mess. There is a plan on how to move forward here
devised by Alexandre Courbot and Mark Brown
- Split off a special <linux/gpio/machine.h> header for the board
gpio table registration, as per example from the regulator
subsystem
- Start to kill off the return value from gpiochip_remove() by
removing the __must_check attribute and removing all checks inside
the drivers/gpio directory. The rationale is: well what were we
supposed to do if there is an error code? Not much: print an error
message. And gpiolib already does that. So make this function
return void eventually
- Some cleanups of hairy gpiolib code, make some functions not to be
used outside the library private and make sure they are not
exported, remove gpiod_lock/unlock_as_irq() as the existing
function is for driver-internal use and fine as it is, delete
gpio_ensure_requested() as it is not meaningful anymore
- Support the GPIOF_ACTIVE_LOW flag from gpio_request_one() function
calls, which is logical since this is already supported when
referencing GPIOs from e.g. device trees
- Switch STMPE, intel-mid, lynxpoint and ACPI (!) to use the gpiolib
irqchip helpers cutting down on GPIO irqchip boilerplate a bit more
- New driver for the Zynq GPIO block
- The usual incremental improvements around a bunch of drivers
- Janitorial syntactic and semantic cleanups by Jingoo Han, and
Rickard Strandqvist especially"
* tag 'gpio-v3.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: (37 commits)
MAINTAINERS: update GPIO include files
gpio: add missing includes in machine.h
gpio: add flags argument to gpiod_get*() functions
MAINTAINERS: Update Samsung pin control entry
gpio / ACPI: Move event handling registration to gpiolib irqchip helpers
gpio: lynxpoint: Convert to use gpiolib irqchip
gpio: split gpiod board registration into machine header
gpio: remove gpio_ensure_requested()
gpio: remove useless check in gpiolib_sysfs_init()
gpiolib: Export gpiochip_request_own_desc and gpiochip_free_own_desc
gpio: move gpio_ensure_requested() into legacy C file
gpio: remove gpiod_lock/unlock_as_irq()
gpio: make gpiochip_get_desc() gpiolib-private
gpio: simplify gpiochip_export()
gpio: remove export of private of_get_named_gpio_flags()
gpio: Add support for GPIOF_ACTIVE_LOW to gpio_request_one functions
gpio: zynq: Clear pending interrupt when enabling a IRQ
gpio: drop retval check enforcing from gpiochip_remove()
gpio: remove all usage of gpio_remove retval in driver/gpio
devicetree: Add Zynq GPIO devicetree bindings documentation
...
Diffstat (limited to 'drivers/gpio/gpio-lynxpoint.c')
-rw-r--r-- | drivers/gpio/gpio-lynxpoint.c | 98 |
1 files changed, 26 insertions, 72 deletions
diff --git a/drivers/gpio/gpio-lynxpoint.c b/drivers/gpio/gpio-lynxpoint.c index 2bea89b72508..ff9eb911b5e4 100644 --- a/drivers/gpio/gpio-lynxpoint.c +++ b/drivers/gpio/gpio-lynxpoint.c @@ -25,9 +25,7 @@ #include <linux/types.h> #include <linux/bitops.h> #include <linux/interrupt.h> -#include <linux/irq.h> #include <linux/gpio.h> -#include <linux/irqdomain.h> #include <linux/slab.h> #include <linux/acpi.h> #include <linux/platform_device.h> @@ -62,7 +60,6 @@ struct lp_gpio { struct gpio_chip chip; - struct irq_domain *domain; struct platform_device *pdev; spinlock_t lock; unsigned long reg_base; @@ -151,7 +148,8 @@ static void lp_gpio_free(struct gpio_chip *chip, unsigned offset) static int lp_irq_type(struct irq_data *d, unsigned type) { - struct lp_gpio *lg = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip); u32 hwirq = irqd_to_hwirq(d); unsigned long flags; u32 value; @@ -236,16 +234,11 @@ static int lp_gpio_direction_output(struct gpio_chip *chip, return 0; } -static int lp_gpio_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct lp_gpio *lg = container_of(chip, struct lp_gpio, chip); - return irq_create_mapping(lg->domain, offset); -} - static void lp_gpio_irq_handler(unsigned hwirq, struct irq_desc *desc) { struct irq_data *data = irq_desc_get_irq_data(desc); - struct lp_gpio *lg = irq_data_get_irq_handler_data(data); + struct gpio_chip *gc = irq_desc_get_handler_data(desc); + struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip); struct irq_chip *chip = irq_data_get_irq_chip(data); u32 base, pin, mask; unsigned long reg, ena, pending; @@ -262,7 +255,7 @@ static void lp_gpio_irq_handler(unsigned hwirq, struct irq_desc *desc) mask = BIT(pin); /* Clear before handling so we don't lose an edge */ outl(mask, reg); - irq = irq_find_mapping(lg->domain, base + pin); + irq = irq_find_mapping(lg->chip.irqdomain, base + pin); generic_handle_irq(irq); } } @@ -279,7 +272,8 @@ static void lp_irq_mask(struct irq_data *d) static void lp_irq_enable(struct irq_data *d) { - struct lp_gpio *lg = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip); u32 hwirq = irqd_to_hwirq(d); unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); unsigned long flags; @@ -291,7 +285,8 @@ static void lp_irq_enable(struct irq_data *d) static void lp_irq_disable(struct irq_data *d) { - struct lp_gpio *lg = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip); u32 hwirq = irqd_to_hwirq(d); unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); unsigned long flags; @@ -301,26 +296,6 @@ static void lp_irq_disable(struct irq_data *d) spin_unlock_irqrestore(&lg->lock, flags); } -static int lp_irq_reqres(struct irq_data *d) -{ - struct lp_gpio *lg = irq_data_get_irq_chip_data(d); - - if (gpio_lock_as_irq(&lg->chip, irqd_to_hwirq(d))) { - dev_err(lg->chip.dev, - "unable to lock HW IRQ %lu for IRQ\n", - irqd_to_hwirq(d)); - return -EINVAL; - } - return 0; -} - -static void lp_irq_relres(struct irq_data *d) -{ - struct lp_gpio *lg = irq_data_get_irq_chip_data(d); - - gpio_unlock_as_irq(&lg->chip, irqd_to_hwirq(d)); -} - static struct irq_chip lp_irqchip = { .name = "LP-GPIO", .irq_mask = lp_irq_mask, @@ -328,8 +303,6 @@ static struct irq_chip lp_irqchip = { .irq_enable = lp_irq_enable, .irq_disable = lp_irq_disable, .irq_set_type = lp_irq_type, - .irq_request_resources = lp_irq_reqres, - .irq_release_resources = lp_irq_relres, .flags = IRQCHIP_SKIP_SET_WAKE, }; @@ -348,22 +321,6 @@ static void lp_gpio_irq_init_hw(struct lp_gpio *lg) } } -static int lp_gpio_irq_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hwirq) -{ - struct lp_gpio *lg = d->host_data; - - irq_set_chip_and_handler(irq, &lp_irqchip, handle_simple_irq); - irq_set_chip_data(irq, lg); - irq_set_irq_type(irq, IRQ_TYPE_NONE); - - return 0; -} - -static const struct irq_domain_ops lp_gpio_irq_ops = { - .map = lp_gpio_irq_map, -}; - static int lp_gpio_probe(struct platform_device *pdev) { struct lp_gpio *lg; @@ -371,7 +328,6 @@ static int lp_gpio_probe(struct platform_device *pdev) struct resource *io_rc, *irq_rc; struct device *dev = &pdev->dev; unsigned long reg_len; - unsigned hwirq; int ret = -ENODEV; lg = devm_kzalloc(dev, sizeof(struct lp_gpio), GFP_KERNEL); @@ -414,27 +370,28 @@ static int lp_gpio_probe(struct platform_device *pdev) gc->can_sleep = false; gc->dev = dev; + ret = gpiochip_add(gc); + if (ret) { + dev_err(dev, "failed adding lp-gpio chip\n"); + return ret; + } + /* set up interrupts */ if (irq_rc && irq_rc->start) { - hwirq = irq_rc->start; - gc->to_irq = lp_gpio_to_irq; - - lg->domain = irq_domain_add_linear(NULL, LP_NUM_GPIO, - &lp_gpio_irq_ops, lg); - if (!lg->domain) - return -ENXIO; - lp_gpio_irq_init_hw(lg); + ret = gpiochip_irqchip_add(gc, &lp_irqchip, 0, + handle_simple_irq, IRQ_TYPE_NONE); + if (ret) { + dev_err(dev, "failed to add irqchip\n"); + gpiochip_remove(gc); + return ret; + } - irq_set_handler_data(hwirq, lg); - irq_set_chained_handler(hwirq, lp_gpio_irq_handler); + gpiochip_set_chained_irqchip(gc, &lp_irqchip, + (unsigned)irq_rc->start, + lp_gpio_irq_handler); } - ret = gpiochip_add(gc); - if (ret) { - dev_err(dev, "failed adding lp-gpio chip\n"); - return ret; - } pm_runtime_enable(dev); return 0; @@ -465,11 +422,8 @@ MODULE_DEVICE_TABLE(acpi, lynxpoint_gpio_acpi_match); static int lp_gpio_remove(struct platform_device *pdev) { struct lp_gpio *lg = platform_get_drvdata(pdev); - int err; pm_runtime_disable(&pdev->dev); - err = gpiochip_remove(&lg->chip); - if (err) - dev_warn(&pdev->dev, "failed to remove gpio_chip.\n"); + gpiochip_remove(&lg->chip); return 0; } |