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-stmpe.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-stmpe.c')
-rw-r--r-- | drivers/gpio/gpio-stmpe.c | 119 |
1 files changed, 28 insertions, 91 deletions
diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index 628b58494294..845025a57240 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c @@ -10,8 +10,6 @@ #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/gpio.h> -#include <linux/irq.h> -#include <linux/irqdomain.h> #include <linux/interrupt.h> #include <linux/of.h> #include <linux/mfd/stmpe.h> @@ -31,9 +29,7 @@ struct stmpe_gpio { struct stmpe *stmpe; struct device *dev; struct mutex irq_lock; - struct irq_domain *domain; unsigned norequest_mask; - /* Caches of interrupt control registers for bus_lock */ u8 regs[CACHE_NR_REGS][CACHE_NR_BANKS]; u8 oldregs[CACHE_NR_REGS][CACHE_NR_BANKS]; @@ -101,13 +97,6 @@ static int stmpe_gpio_direction_input(struct gpio_chip *chip, return stmpe_set_bits(stmpe, reg, mask, 0); } -static int stmpe_gpio_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(chip); - - return irq_create_mapping(stmpe_gpio->domain, offset); -} - static int stmpe_gpio_request(struct gpio_chip *chip, unsigned offset) { struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(chip); @@ -126,14 +115,14 @@ static struct gpio_chip template_chip = { .get = stmpe_gpio_get, .direction_output = stmpe_gpio_direction_output, .set = stmpe_gpio_set, - .to_irq = stmpe_gpio_to_irq, .request = stmpe_gpio_request, .can_sleep = true, }; static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type) { - struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(gc); int offset = d->hwirq; int regoffset = offset / 8; int mask = 1 << (offset % 8); @@ -160,14 +149,16 @@ static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type) static void stmpe_gpio_irq_lock(struct irq_data *d) { - struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(gc); mutex_lock(&stmpe_gpio->irq_lock); } static void stmpe_gpio_irq_sync_unlock(struct irq_data *d) { - struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(gc); struct stmpe *stmpe = stmpe_gpio->stmpe; int num_banks = DIV_ROUND_UP(stmpe->num_gpios, 8); static const u8 regmap[] = { @@ -200,7 +191,8 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d) static void stmpe_gpio_irq_mask(struct irq_data *d) { - struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(gc); int offset = d->hwirq; int regoffset = offset / 8; int mask = 1 << (offset % 8); @@ -210,7 +202,8 @@ static void stmpe_gpio_irq_mask(struct irq_data *d) static void stmpe_gpio_irq_unmask(struct irq_data *d) { - struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(gc); int offset = d->hwirq; int regoffset = offset / 8; int mask = 1 << (offset % 8); @@ -253,7 +246,7 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) while (stat) { int bit = __ffs(stat); int line = bank * 8 + bit; - int child_irq = irq_find_mapping(stmpe_gpio->domain, + int child_irq = irq_find_mapping(stmpe_gpio->chip.irqdomain, line); handle_nested_irq(child_irq); @@ -271,56 +264,6 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) return IRQ_HANDLED; } -static int stmpe_gpio_irq_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hwirq) -{ - struct stmpe_gpio *stmpe_gpio = d->host_data; - - if (!stmpe_gpio) - return -EINVAL; - - irq_set_chip_data(irq, stmpe_gpio); - irq_set_chip_and_handler(irq, &stmpe_gpio_irq_chip, - handle_simple_irq); - irq_set_nested_thread(irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(irq, IRQF_VALID); -#else - irq_set_noprobe(irq); -#endif - - return 0; -} - -static void stmpe_gpio_irq_unmap(struct irq_domain *d, unsigned int irq) -{ -#ifdef CONFIG_ARM - set_irq_flags(irq, 0); -#endif - irq_set_chip_and_handler(irq, NULL, NULL); - irq_set_chip_data(irq, NULL); -} - -static const struct irq_domain_ops stmpe_gpio_irq_simple_ops = { - .unmap = stmpe_gpio_irq_unmap, - .map = stmpe_gpio_irq_map, - .xlate = irq_domain_xlate_twocell, -}; - -static int stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio, - struct device_node *np) -{ - stmpe_gpio->domain = irq_domain_add_simple(np, - stmpe_gpio->chip.ngpio, 0, - &stmpe_gpio_irq_simple_ops, stmpe_gpio); - if (!stmpe_gpio->domain) { - dev_err(stmpe_gpio->dev, "failed to create irqdomain\n"); - return -ENOSYS; - } - - return 0; -} - static int stmpe_gpio_probe(struct platform_device *pdev) { struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); @@ -358,30 +301,37 @@ static int stmpe_gpio_probe(struct platform_device *pdev) if (irq < 0) dev_info(&pdev->dev, - "device configured in no-irq mode; " + "device configured in no-irq mode: " "irqs are not available\n"); ret = stmpe_enable(stmpe, STMPE_BLOCK_GPIO); if (ret) goto out_free; - if (irq >= 0) { - ret = stmpe_gpio_irq_init(stmpe_gpio, np); - if (ret) - goto out_disable; - - ret = request_threaded_irq(irq, NULL, stmpe_gpio_irq, - IRQF_ONESHOT, "stmpe-gpio", stmpe_gpio); + if (irq > 0) { + ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, + stmpe_gpio_irq, IRQF_ONESHOT, + "stmpe-gpio", stmpe_gpio); if (ret) { dev_err(&pdev->dev, "unable to get irq: %d\n", ret); goto out_disable; } + ret = gpiochip_irqchip_add(&stmpe_gpio->chip, + &stmpe_gpio_irq_chip, + 0, + handle_simple_irq, + IRQ_TYPE_NONE); + if (ret) { + dev_err(&pdev->dev, + "could not connect irqchip to gpiochip\n"); + return ret; + } } ret = gpiochip_add(&stmpe_gpio->chip); if (ret) { dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret); - goto out_freeirq; + goto out_disable; } if (pdata && pdata->setup) @@ -391,9 +341,6 @@ static int stmpe_gpio_probe(struct platform_device *pdev) return 0; -out_freeirq: - if (irq >= 0) - free_irq(irq, stmpe_gpio); out_disable: stmpe_disable(stmpe, STMPE_BLOCK_GPIO); out_free: @@ -406,24 +353,14 @@ static int stmpe_gpio_remove(struct platform_device *pdev) struct stmpe_gpio *stmpe_gpio = platform_get_drvdata(pdev); struct stmpe *stmpe = stmpe_gpio->stmpe; struct stmpe_gpio_platform_data *pdata = stmpe->pdata->gpio; - int irq = platform_get_irq(pdev, 0); - int ret; if (pdata && pdata->remove) pdata->remove(stmpe, stmpe_gpio->chip.base); - ret = gpiochip_remove(&stmpe_gpio->chip); - if (ret < 0) { - dev_err(stmpe_gpio->dev, - "unable to remove gpiochip: %d\n", ret); - return ret; - } + gpiochip_remove(&stmpe_gpio->chip); stmpe_disable(stmpe, STMPE_BLOCK_GPIO); - if (irq >= 0) - free_irq(irq, stmpe_gpio); - kfree(stmpe_gpio); return 0; |