This is the bulk of GPIO changes for the v3.16 series:

- We are finalizing and fixing up the gpiochip irqchip helpers
   bringing a helpful irqchip implementation into the gpiolib
   core and avoiding duplicate code and, more importantly,
   duplicate bug fixes:
 
   - Support for using the helpers with threaded interrupt
     handlers as used on sleeping GPIO-irqchips
 
   - Do not set up hardware triggers for edges or levels if
     the default IRQ type is IRQ_TYPE_NONE - some drivers
     would exploit the fact that you could get default
     initialization of the IRQ type from the core at probe()
     but if no default type is set up from the helper, we
     should not call the driver to configure anything. Wait
     until a consumer requests the interrupt instead.
 
   - Make the irqchip helpers put the GPIO irqs into their
     own lock class. The GPIO irqchips can often emit
     (harmless, but annoying) lockdep warnings about recursions
     when they are in fact just cascaded IRQs. By putting
     them into their own lock class we help the lockdep core
     to keep track of things.
 
   - Switch the tc3589x GPIO expanders to use the irqchip
     helpers
 
   - Switch the OMAP GPIO driver to use the irqchip helpers
 
   - Add some documentation for the irqchip helpers
 
   - select IRQ_DOMAIN when using the helpers since some
     platforms may not be using this by default and it's a
     strict dependency.
 
 - Continued GPIO descriptor refactoring:
 
   - Remove the one instance of gpio_to_desc() from the
     device tree code, making the OF GPIO code use GPIO
     descriptors only.
 
   - Introduce gpiod_get_optional() and
     gpiod_get_optional_index() akin to the similar
     regulator functions for cases where the use of GPIO
     is optional and not strictly required.
 
   - Make of_get_named_gpiod_flags() private - we do not
     want to unnecessarily expose APIs to drivers that
     make the gpiolib harder than necessary to maintain
     and refactor. Privatize this function.
 
 - Support "-gpio" suffix for the OF GPIO retrieveal path.
   We used to look for "foo-gpios" or just "gpios" in device
   tree nodes, but it turns out that some drivers with a
   single GPIO line will just state "foo-gpio" (singularis).
   Sigh. Support this with a fallback looking for it, as
   this simplifies driver code and handles it in core code.
 
 - Switch the ACPI GPIO core to fetch GPIOs with the
   *_cansleep function variants as the GPIO operation
   region handler can sleep, and shall be able to handle
   gpiochips that sleep.
 
 - Tons of cleanups and janitorial work from Jingoo Han,
   Axel Lin, Javier Martinez Canillas and Abdoulaye Berthe.
   Notably Jingoo cut off a ton of pointless OOM messages.
 
 - Incremental development and fixes for various drivers,
   nothing really special here.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJTjDSbAAoJEEEQszewGV1zcwcQAI/fwAw2B8kelDMaB1ggQeAU
 cyXrr9vVXYMztOoYkYcbZq0stuvZT+CDCVJPqPqntYYssAJf/2m3xWEhz4XFcGui
 THTNIaFLc9f7JvTFfWS0VzwPzqPp/XkUiAyDzYMK0Wso6AP853IB4LlHDMvC9jpM
 brMo+zdhnASayhumAL8kp0XVal7d/3IAy/v7Q6ebpqoP5AnhC8NT8ysh2raGdVLa
 4+W9hMtflq8u+gllxul71Mf1L3CD0x3UybMbsx4k0Z+60uYjiIhhbHdGxRVH3YAU
 DZ40RW6ARU1mXuUlSjBIbgN1fzxCKNQFR7MsDruiSR0ohHEa8dc3o1AktdRKGoQl
 +sUMSQI3G4tlLOhVYIOx+kOF4DJWNNFYNdvT/ut0NwKohma2nZt9LDyqp92XZKt9
 gVufvJzFe94re/bAMAz41PRm3wnzmuUSAq649r0RIQ4Yp74f5n5EO9WnnI/CIVlw
 pAFsLJZZhh47I6IxMmIPBjiy8QWVdvRwsBIrV0pDoZGQjjm2S1MHi+5pLghHRROq
 qtrRG1SIAptoaEDWM0WdVPT4Jcx+3QzU9YjlCiXxd8qQl4lRHAJRCYbxGYsK0a8b
 eXQ5N4CHy2jOUTKhmT2ISLmC6EWurabSh9eWwmk2R2gBmwG6AKoI60MKFtcx53tz
 3fQN3Oy8zaNyIL6/2aoN
 =M59o
 -----END PGP SIGNATURE-----

Merge tag 'gpio-v3.16-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio into next

Pull GPIO updates from Linus Walleij:
 "This is the bulk of GPIO changes for the v3.16 series.

  There is a lot of action in the GPIO subsystem doing refactorings and
  cleanups, almost as many deletions as insertions and minor feature
  growth and no new drivers this time.  Which is actually pretty nice.
  Some GPIO-related stuff will come in through the pin control tree as
  well.

  Details:

   - We are finalizing and fixing up the gpiochip irqchip helpers
     bringing a helpful irqchip implementation into the gpiolib core and
     avoiding duplicate code and, more importantly, duplicate bug fixes:

     * Support for using the helpers with threaded interrupt handlers as
       used on sleeping GPIO-irqchips

     * Do not set up hardware triggers for edges or levels if the
       default IRQ type is IRQ_TYPE_NONE - some drivers would exploit
       the fact that you could get default initialization of the IRQ
       type from the core at probe() but if no default type is set up
       from the helper, we should not call the driver to configure
       anything.  Wait until a consumer requests the interrupt instead.

     * Make the irqchip helpers put the GPIO irqs into their own lock
       class.  The GPIO irqchips can often emit (harmless, but annoying)
       lockdep warnings about recursions when they are in fact just
       cascaded IRQs.  By putting them into their own lock class we help
       the lockdep core to keep track of things.

     * Switch the tc3589x GPIO expanders to use the irqchip helpers

     * Switch the OMAP GPIO driver to use the irqchip helpers

     * Add some documentation for the irqchip helpers

     * select IRQ_DOMAIN when using the helpers since some platforms may
       not be using this by default and it's a strict dependency.

   - Continued GPIO descriptor refactoring:

     * Remove the one instance of gpio_to_desc() from the device tree
       code, making the OF GPIO code use GPIO descriptors only.

     * Introduce gpiod_get_optional() and gpiod_get_optional_index()
       akin to the similar regulator functions for cases where the use
       of GPIO is optional and not strictly required.

     * Make of_get_named_gpiod_flags() private - we do not want to
       unnecessarily expose APIs to drivers that make the gpiolib harder
       than necessary to maintain and refactor.  Privatize this
       function.

   - Support "-gpio" suffix for the OF GPIO retrieveal path.  We used to
     look for "foo-gpios" or just "gpios" in device tree nodes, but it
     turns out that some drivers with a single GPIO line will just state
     "foo-gpio" (singularis).  Sigh.  Support this with a fallback
     looking for it, as this simplifies driver code and handles it in
     core code.

   - Switch the ACPI GPIO core to fetch GPIOs with the *_cansleep
     function variants as the GPIO operation region handler can sleep,
     and shall be able to handle gpiochips that sleep.

   - Tons of cleanups and janitorial work from Jingoo Han, Axel Lin,
     Javier Martinez Canillas and Abdoulaye Berthe.  Notably Jingoo cut
     off a ton of pointless OOM messages.

   - Incremental development and fixes for various drivers, nothing
     really special here"

* tag 'gpio-v3.16-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: (85 commits)
  gpio: select IRQ_DOMAIN for gpiolib irqchip helpers
  gpio: pca953x: use gpiolib irqchip helpers
  gpio: pcf857x: Add IRQF_SHARED when request irq
  gpio: pcf857x: Avoid calling irq_domain_cleanup twice
  gpio: mcp23s08: switch chip count to int
  gpio: dwapb: use a second irq chip
  gpio: ep93xx: Use devm_ioremap_resource()
  gpio: mcp23s08: fixed count variable for devicetree probing
  gpio: Add run-time dependencies to R-Car driver
  gpio: pch: add slab include
  Documentation / ACPI: Fix location of GPIO documentation
  gpio / ACPI: use *_cansleep version of gpiod_get/set APIs
  gpio: generic: add request function pointer
  gpio-pch: Fix Kconfig dependencies
  gpio: make of_get_named_gpiod_flags() private
  gpio: gpioep93xx: use devm functions
  gpio: janzttl: use devm function
  gpio: timberdale: use devm functions
  gpio: bt8xx: use devm function for memory allocation
  gpio: include linux/bug.h in interface header
  ...
This commit is contained in:
Linus Torvalds 2014-06-02 08:46:03 -07:00
Родитель 9f888b3a10 fc34627012
Коммит 80fb974798
53 изменённых файлов: 706 добавлений и 687 удалений

Просмотреть файл

@ -296,7 +296,7 @@ specifies the path to the controller. In order to use these GPIOs in Linux
we need to translate them to the corresponding Linux GPIO descriptors.
There is a standard GPIO API for that and is documented in
Documentation/gpio.txt.
Documentation/gpio/.
In the above example we can get the corresponding two GPIO descriptors with
a code like this:

Просмотреть файл

@ -21,6 +21,12 @@ Required Properties:
GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported.
- gpio-ranges: Range of pins managed by the GPIO controller.
Optional properties:
- clocks: Must contain a reference to the functional clock. The property is
mandatory if the hardware implements a controllable functional clock for
the GPIO instance.
Please refer to gpio.txt in this directory for details of gpio-ranges property
and the common GPIO bindings used by client devices.

Просмотреть файл

@ -308,3 +308,10 @@ SLAVE DMA ENGINE
SPI
devm_spi_register_master()
GPIO
devm_gpiod_get()
devm_gpiod_get_index()
devm_gpiod_get_optional()
devm_gpiod_get_index_optional()
devm_gpiod_put()

Просмотреть файл

@ -73,6 +73,65 @@ The IRQ portions of the GPIO block are implemented using an irqchip, using
the header <linux/irq.h>. So basically such a driver is utilizing two sub-
systems simultaneously: gpio and irq.
GPIO irqchips usually fall in one of two categories:
* CHAINED GPIO irqchips: these are usually the type that is embedded on
an SoC. This means that there is a fast IRQ handler for the GPIOs that
gets called in a chain from the parent IRQ handler, most typically the
system interrupt controller. This means the GPIO irqchip is registered
using irq_set_chained_handler() or the corresponding
gpiochip_set_chained_irqchip() helper function, and the GPIO irqchip
handler will be called immediately from the parent irqchip, while
holding the IRQs disabled. The GPIO irqchip will then end up calling
something like this sequence in its interrupt handler:
static irqreturn_t tc3589x_gpio_irq(int irq, void *data)
chained_irq_enter(...);
generic_handle_irq(...);
chained_irq_exit(...);
Chained GPIO irqchips typically can NOT set the .can_sleep flag on
struct gpio_chip, as everything happens directly in the callbacks.
* NESTED THREADED GPIO irqchips: these are off-chip GPIO expanders and any
other GPIO irqchip residing on the other side of a sleeping bus. Of course
such drivers that need slow bus traffic to read out IRQ status and similar,
traffic which may in turn incur other IRQs to happen, cannot be handled
in a quick IRQ handler with IRQs disabled. Instead they need to spawn a
thread and then mask the parent IRQ line until the interrupt is handled
by the driver. The hallmark of this driver is to call something like
this in its interrupt handler:
static irqreturn_t tc3589x_gpio_irq(int irq, void *data)
...
handle_nested_irq(irq);
The hallmark of threaded GPIO irqchips is that they set the .can_sleep
flag on struct gpio_chip to true, indicating that this chip may sleep
when accessing the GPIOs.
To help out in handling the set-up and management of GPIO irqchips and the
associated irqdomain and resource allocation callbacks, the gpiolib has
some helpers that can be enabled by selecting the GPIOLIB_IRQCHIP Kconfig
symbol:
* gpiochip_irqchip_add(): adds an irqchip to a gpiochip. It will pass
the struct gpio_chip* for the chip to all IRQ callbacks, so the callbacks
need to embed the gpio_chip in its state container and obtain a pointer
to the container using container_of().
(See Documentation/driver-model/design-patterns.txt)
* gpiochip_set_chained_irqchip(): sets up a chained irq handler for a
gpio_chip from a parent IRQ and passes the struct gpio_chip* as handler
data. (Notice handler data, since the irqchip data is likely used by the
parent irqchip!) This is for the chained type of chip.
To use the helpers please keep the following in mind:
- Make sure to assign all relevant members of the struct gpio_chip so that
the irqchip can initialize. E.g. .dev and .can_sleep shall be set up
properly.
It is legal for any IRQ consumer to request an IRQ from any irqchip no matter
if that is a combined GPIO+IRQ driver. The basic premise is that gpio_chip and
irq_chip are orthogonal, and offering their services independent of each

Просмотреть файл

@ -6418,6 +6418,7 @@ F: drivers/usb/*/*omap*
F: arch/arm/*omap*/usb*
OMAP GPIO DRIVER
M: Javier Martinez Canillas <javier@dowhile0.org>
M: Santosh Shilimkar <santosh.shilimkar@ti.com>
M: Kevin Hilman <khilman@deeprootsystems.com>
L: linux-omap@vger.kernel.org

Просмотреть файл

@ -56,6 +56,7 @@ config GPIO_ACPI
depends on ACPI
config GPIOLIB_IRQCHIP
select IRQ_DOMAIN
bool
config DEBUG_GPIO
@ -243,6 +244,15 @@ config GPIO_OCTEON
Say yes here to support the on-chip GPIO lines on the OCTEON
family of SOCs.
config GPIO_OMAP
bool "TI OMAP GPIO support" if COMPILE_TEST && !ARCH_OMAP2PLUS
default y if ARCH_OMAP
depends on ARM
select GENERIC_IRQ_CHIP
select GPIOLIB_IRQCHIP
help
Say yes here to enable GPIO support for TI OMAP SoCs.
config GPIO_PL061
bool "PrimeCell PL061 GPIO support"
depends on ARM_AMBA
@ -259,7 +269,7 @@ config GPIO_PXA
config GPIO_RCAR
tristate "Renesas R-Car GPIO"
depends on ARM
depends on ARM && (ARCH_SHMOBILE || COMPILE_TEST)
help
Say yes here to support GPIO on Renesas R-Car SoCs.
@ -510,6 +520,7 @@ config GPIO_PCA953X
config GPIO_PCA953X_IRQ
bool "Interrupt controller support for PCA953x"
depends on GPIO_PCA953X=y
select GPIOLIB_IRQCHIP
help
Say yes here to enable the pca953x to be used as an interrupt
controller. It requires the driver to be built in the kernel.
@ -579,6 +590,7 @@ config GPIO_STP_XWAY
config GPIO_TC3589X
bool "TC3589X GPIOs"
depends on MFD_TC3589X
select GPIOLIB_IRQCHIP
help
This enables support for the GPIOs found on the TC3589X
I/O Expander.
@ -699,13 +711,13 @@ config GPIO_AMD8111
config GPIO_INTEL_MID
bool "Intel Mid GPIO support"
depends on PCI && X86
select IRQ_DOMAIN
select GPIOLIB_IRQCHIP
help
Say Y here to support Intel Mid GPIO.
config GPIO_PCH
tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7223/ML7831) GPIO"
depends on PCI && X86
depends on PCI && (X86_32 || COMPILE_TEST)
select GENERIC_IRQ_CHIP
help
This driver is for PCH(Platform controller Hub) GPIO of Intel Topcliff
@ -739,7 +751,7 @@ config GPIO_SODAVILLE
config GPIO_TIMBERDALE
bool "Support for timberdale GPIO IP"
depends on MFD_TIMBERDALE && HAS_IOMEM
depends on MFD_TIMBERDALE
---help---
Add support for the GPIO IP in the timberdale FPGA.

Просмотреть файл

@ -58,7 +58,7 @@ obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o
obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o
obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o
obj-$(CONFIG_GPIO_OCTEON) += gpio-octeon.o
obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o
obj-$(CONFIG_GPIO_OMAP) += gpio-omap.o
obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o
obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o
obj-$(CONFIG_GPIO_PCH) += gpio-pch.o

Просмотреть файл

@ -51,6 +51,22 @@ struct gpio_desc *__must_check devm_gpiod_get(struct device *dev,
}
EXPORT_SYMBOL(devm_gpiod_get);
/**
* devm_gpiod_get_optional - Resource-managed gpiod_get_optional()
* @dev: GPIO consumer
* @con_id: function within the GPIO consumer
*
* Managed gpiod_get_optional(). GPIO descriptors returned from this function
* are automatically disposed on driver detach. See gpiod_get_optional() for
* detailed information about behavior and return values.
*/
struct gpio_desc *__must_check devm_gpiod_get_optional(struct device *dev,
const char *con_id)
{
return devm_gpiod_get_index_optional(dev, con_id, 0);
}
EXPORT_SYMBOL(devm_gpiod_get_optional);
/**
* devm_gpiod_get_index - Resource-managed gpiod_get_index()
* @dev: GPIO consumer
@ -86,6 +102,33 @@ struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
}
EXPORT_SYMBOL(devm_gpiod_get_index);
/**
* devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional()
* @dev: GPIO consumer
* @con_id: function within the GPIO consumer
* @index: index of the GPIO to obtain in the consumer
*
* Managed gpiod_get_index_optional(). GPIO descriptors returned from this
* function are automatically disposed on driver detach. See
* gpiod_get_index_optional() for detailed information about behavior and
* return values.
*/
struct gpio_desc *__must_check devm_gpiod_get_index_optional(struct device *dev,
const char *con_id,
unsigned int index)
{
struct gpio_desc *desc;
desc = devm_gpiod_get_index(dev, con_id, index);
if (IS_ERR(desc)) {
if (PTR_ERR(desc) == -ENOENT)
return NULL;
}
return desc;
}
EXPORT_SYMBOL(devm_gpiod_get_index_optional);
/**
* devm_gpiod_put - Resource-managed gpiod_put()
* @desc: GPIO descriptor to dispose of

Просмотреть файл

@ -106,10 +106,8 @@ static int adp5520_gpio_probe(struct platform_device *pdev)
}
dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
if (dev == NULL) {
dev_err(&pdev->dev, "failed to alloc memory\n");
if (dev == NULL)
return -ENOMEM;
}
dev->master = pdev->dev.parent;

Просмотреть файл

@ -379,10 +379,8 @@ static int adp5588_gpio_probe(struct i2c_client *client,
}
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (dev == NULL) {
dev_err(&client->dev, "failed to alloc memory\n");
if (dev == NULL)
return -ENOMEM;
}
dev->client = client;

Просмотреть файл

@ -178,7 +178,7 @@ static int bt8xxgpio_probe(struct pci_dev *dev,
struct bt8xxgpio *bg;
int err;
bg = kzalloc(sizeof(*bg), GFP_KERNEL);
bg = devm_kzalloc(&dev->dev, sizeof(struct bt8xxgpio), GFP_KERNEL);
if (!bg)
return -ENOMEM;
@ -188,9 +188,9 @@ static int bt8xxgpio_probe(struct pci_dev *dev,
err = pci_enable_device(dev);
if (err) {
printk(KERN_ERR "bt8xxgpio: Can't enable device.\n");
goto err_freebg;
return err;
}
if (!request_mem_region(pci_resource_start(dev, 0),
if (!devm_request_mem_region(&dev->dev, pci_resource_start(dev, 0),
pci_resource_len(dev, 0),
"bt8xxgpio")) {
printk(KERN_WARNING "bt8xxgpio: Can't request iomem (0x%llx).\n",
@ -201,11 +201,11 @@ static int bt8xxgpio_probe(struct pci_dev *dev,
pci_set_master(dev);
pci_set_drvdata(dev, bg);
bg->mmio = ioremap(pci_resource_start(dev, 0), 0x1000);
bg->mmio = devm_ioremap(&dev->dev, pci_resource_start(dev, 0), 0x1000);
if (!bg->mmio) {
printk(KERN_ERR "bt8xxgpio: ioremap() failed\n");
err = -EIO;
goto err_release_mem;
goto err_disable;
}
/* Disable interrupts */
@ -220,18 +220,13 @@ static int bt8xxgpio_probe(struct pci_dev *dev,
err = gpiochip_add(&bg->gpio);
if (err) {
printk(KERN_ERR "bt8xxgpio: Failed to register GPIOs\n");
goto err_release_mem;
goto err_disable;
}
return 0;
err_release_mem:
release_mem_region(pci_resource_start(dev, 0),
pci_resource_len(dev, 0));
err_disable:
pci_disable_device(dev);
err_freebg:
kfree(bg);
return err;
}
@ -250,8 +245,6 @@ static void bt8xxgpio_remove(struct pci_dev *pdev)
release_mem_region(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0));
pci_disable_device(pdev);
kfree(bg);
}
#ifdef CONFIG_PM

Просмотреть файл

@ -230,10 +230,8 @@ static int davinci_gpio_probe(struct platform_device *pdev)
chips = devm_kzalloc(dev,
ngpio * sizeof(struct davinci_gpio_controller),
GFP_KERNEL);
if (!chips) {
dev_err(dev, "Memory allocation failed\n");
if (!chips)
return -ENOMEM;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {

Просмотреть файл

@ -198,6 +198,8 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)
break;
}
irq_setup_alt_chip(d, type);
writel(level, gpio->regs + GPIO_INTTYPE_LEVEL);
writel(polarity, gpio->regs + GPIO_INT_POLARITY);
spin_unlock_irqrestore(&bgc->lock, flags);
@ -213,7 +215,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
struct irq_chip_generic *irq_gc;
unsigned int hwirq, ngpio = gc->ngpio;
struct irq_chip_type *ct;
int err, irq;
int err, irq, i;
irq = irq_of_parse_and_map(node, 0);
if (!irq) {
@ -227,7 +229,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
if (!gpio->domain)
return;
err = irq_alloc_domain_generic_chips(gpio->domain, ngpio, 1,
err = irq_alloc_domain_generic_chips(gpio->domain, ngpio, 2,
"gpio-dwapb", handle_level_irq,
IRQ_NOREQUEST, 0,
IRQ_GC_INIT_NESTED_LOCK);
@ -248,20 +250,24 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
irq_gc->reg_base = gpio->regs;
irq_gc->private = gpio;
ct = irq_gc->chip_types;
ct->chip.irq_ack = irq_gc_ack_set_bit;
ct->chip.irq_mask = irq_gc_mask_set_bit;
ct->chip.irq_unmask = irq_gc_mask_clr_bit;
ct->chip.irq_set_type = dwapb_irq_set_type;
ct->chip.irq_enable = dwapb_irq_enable;
ct->chip.irq_disable = dwapb_irq_disable;
ct->chip.irq_request_resources = dwapb_irq_reqres;
ct->chip.irq_release_resources = dwapb_irq_relres;
ct->regs.ack = GPIO_PORTA_EOI;
ct->regs.mask = GPIO_INTMASK;
for (i = 0; i < 2; i++) {
ct = &irq_gc->chip_types[i];
ct->chip.irq_ack = irq_gc_ack_set_bit;
ct->chip.irq_mask = irq_gc_mask_set_bit;
ct->chip.irq_unmask = irq_gc_mask_clr_bit;
ct->chip.irq_set_type = dwapb_irq_set_type;
ct->chip.irq_enable = dwapb_irq_enable;
ct->chip.irq_disable = dwapb_irq_disable;
ct->chip.irq_request_resources = dwapb_irq_reqres;
ct->chip.irq_release_resources = dwapb_irq_relres;
ct->regs.ack = GPIO_PORTA_EOI;
ct->regs.mask = GPIO_INTMASK;
ct->type = IRQ_TYPE_LEVEL_MASK;
}
irq_setup_generic_chip(irq_gc, IRQ_MSK(port->bgc.gc.ngpio),
IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0);
irq_gc->chip_types[0].type = IRQ_TYPE_LEVEL_MASK;
irq_gc->chip_types[1].type = IRQ_TYPE_EDGE_BOTH;
irq_gc->chip_types[1].handler = handle_edge_irq;
irq_set_chained_handler(irq, dwapb_irq_handler);
irq_set_handler_data(irq, gpio);

Просмотреть файл

@ -212,7 +212,7 @@ static void __em_gio_set(struct gpio_chip *chip, unsigned int reg,
{
/* upper 16 bits contains mask and lower 16 actual value */
em_gio_write(gpio_to_priv(chip), reg,
(1 << (shift + 16)) | (value << shift));
(BIT(shift + 16)) | (value << shift));
}
static void em_gio_set(struct gpio_chip *chip, unsigned offset, int value)
@ -284,7 +284,6 @@ static int em_gio_probe(struct platform_device *pdev)
p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
if (!p) {
dev_err(&pdev->dev, "failed to allocate driver data\n");
ret = -ENOMEM;
goto err0;
}

Просмотреть файл

@ -344,37 +344,24 @@ static int ep93xx_gpio_probe(struct platform_device *pdev)
{
struct ep93xx_gpio *ep93xx_gpio;
struct resource *res;
void __iomem *mmio;
int i;
int ret;
struct device *dev = &pdev->dev;
ep93xx_gpio = kzalloc(sizeof(*ep93xx_gpio), GFP_KERNEL);
ep93xx_gpio = devm_kzalloc(dev, sizeof(struct ep93xx_gpio), GFP_KERNEL);
if (!ep93xx_gpio)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
ret = -ENXIO;
goto exit_free;
}
if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
ret = -EBUSY;
goto exit_free;
}
mmio = ioremap(res->start, resource_size(res));
if (!mmio) {
ret = -ENXIO;
goto exit_release;
}
ep93xx_gpio->mmio_base = mmio;
ep93xx_gpio->mmio_base = devm_ioremap_resource(dev, res);
if (IS_ERR(ep93xx_gpio->mmio_base))
return PTR_ERR(ep93xx_gpio->mmio_base);
for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
struct bgpio_chip *bgc = &ep93xx_gpio->bgc[i];
struct ep93xx_gpio_bank *bank = &ep93xx_gpio_banks[i];
if (ep93xx_gpio_add_bank(bgc, &pdev->dev, mmio, bank))
if (ep93xx_gpio_add_bank(bgc, &pdev->dev,
ep93xx_gpio->mmio_base, bank))
dev_warn(&pdev->dev, "Unable to add gpio bank %s\n",
bank->label);
}
@ -382,13 +369,6 @@ static int ep93xx_gpio_probe(struct platform_device *pdev)
ep93xx_gpio_init_irq();
return 0;
exit_release:
release_mem_region(res->start, resource_size(res));
exit_free:
kfree(ep93xx_gpio);
dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, ret);
return ret;
}
static struct platform_driver ep93xx_gpio_driver = {

Просмотреть файл

@ -18,15 +18,9 @@
*/
#include <linux/kernel.h>
#include <linux/compiler.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/module.h>
#define GEF_GPIO_DIRECT 0x00
@ -39,28 +33,26 @@
#define GEF_GPIO_OVERRUN 0x1C
#define GEF_GPIO_MODE 0x20
static void _gef_gpio_set(void __iomem *reg, unsigned int offset, int value)
static void gef_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
unsigned int data;
data = ioread32be(reg);
/* value: 0=low; 1=high */
if (value & 0x1)
data = data | (0x1 << offset);
data = ioread32be(mmchip->regs + GEF_GPIO_OUT);
if (value)
data = data | BIT(offset);
else
data = data & ~(0x1 << offset);
iowrite32be(data, reg);
data = data & ~BIT(offset);
iowrite32be(data, mmchip->regs + GEF_GPIO_OUT);
}
static int gef_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
{
unsigned int data;
struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT);
data = data | (0x1 << offset);
data = data | BIT(offset);
iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT);
return 0;
@ -71,11 +63,11 @@ static int gef_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
unsigned int data;
struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
/* Set direction before switching to input */
_gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
/* Set value before switching to output */
gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT);
data = data & ~(0x1 << offset);
data = data & ~BIT(offset);
iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT);
return 0;
@ -83,116 +75,56 @@ static int gef_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
static int gef_gpio_get(struct gpio_chip *chip, unsigned offset)
{
unsigned int data;
int state = 0;
struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
data = ioread32be(mmchip->regs + GEF_GPIO_IN);
state = (int)((data >> offset) & 0x1);
return state;
return !!(ioread32be(mmchip->regs + GEF_GPIO_IN) & BIT(offset));
}
static void gef_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
_gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
}
static int __init gef_gpio_init(void)
{
struct device_node *np;
int retval;
struct of_mm_gpio_chip *gef_gpio_chip;
for_each_compatible_node(np, NULL, "gef,sbc610-gpio") {
pr_debug("%s: Initialising GEF GPIO\n", np->full_name);
/* Allocate chip structure */
gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL);
if (!gef_gpio_chip) {
pr_err("%s: Unable to allocate structure\n",
np->full_name);
continue;
}
/* Setup pointers to chip functions */
gef_gpio_chip->gc.of_gpio_n_cells = 2;
gef_gpio_chip->gc.ngpio = 19;
gef_gpio_chip->gc.direction_input = gef_gpio_dir_in;
gef_gpio_chip->gc.direction_output = gef_gpio_dir_out;
gef_gpio_chip->gc.get = gef_gpio_get;
gef_gpio_chip->gc.set = gef_gpio_set;
/* This function adds a memory mapped GPIO chip */
retval = of_mm_gpiochip_add(np, gef_gpio_chip);
if (retval) {
kfree(gef_gpio_chip);
pr_err("%s: Unable to add GPIO\n", np->full_name);
}
}
for_each_compatible_node(np, NULL, "gef,sbc310-gpio") {
pr_debug("%s: Initialising GEF GPIO\n", np->full_name);
/* Allocate chip structure */
gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL);
if (!gef_gpio_chip) {
pr_err("%s: Unable to allocate structure\n",
np->full_name);
continue;
}
/* Setup pointers to chip functions */
gef_gpio_chip->gc.of_gpio_n_cells = 2;
gef_gpio_chip->gc.ngpio = 6;
gef_gpio_chip->gc.direction_input = gef_gpio_dir_in;
gef_gpio_chip->gc.direction_output = gef_gpio_dir_out;
gef_gpio_chip->gc.get = gef_gpio_get;
gef_gpio_chip->gc.set = gef_gpio_set;
/* This function adds a memory mapped GPIO chip */
retval = of_mm_gpiochip_add(np, gef_gpio_chip);
if (retval) {
kfree(gef_gpio_chip);
pr_err("%s: Unable to add GPIO\n", np->full_name);
}
}
for_each_compatible_node(np, NULL, "ge,imp3a-gpio") {
pr_debug("%s: Initialising GE GPIO\n", np->full_name);
/* Allocate chip structure */
gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL);
if (!gef_gpio_chip) {
pr_err("%s: Unable to allocate structure\n",
np->full_name);
continue;
}
/* Setup pointers to chip functions */
gef_gpio_chip->gc.of_gpio_n_cells = 2;
gef_gpio_chip->gc.ngpio = 16;
gef_gpio_chip->gc.direction_input = gef_gpio_dir_in;
gef_gpio_chip->gc.direction_output = gef_gpio_dir_out;
gef_gpio_chip->gc.get = gef_gpio_get;
gef_gpio_chip->gc.set = gef_gpio_set;
/* This function adds a memory mapped GPIO chip */
retval = of_mm_gpiochip_add(np, gef_gpio_chip);
if (retval) {
kfree(gef_gpio_chip);
pr_err("%s: Unable to add GPIO\n", np->full_name);
}
}
return 0;
static const struct of_device_id gef_gpio_ids[] = {
{
.compatible = "gef,sbc610-gpio",
.data = (void *)19,
}, {
.compatible = "gef,sbc310-gpio",
.data = (void *)6,
}, {
.compatible = "ge,imp3a-gpio",
.data = (void *)16,
},
{ }
};
arch_initcall(gef_gpio_init);
MODULE_DEVICE_TABLE(of, gef_gpio_ids);
static int __init gef_gpio_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id =
of_match_device(gef_gpio_ids, &pdev->dev);
struct of_mm_gpio_chip *mmchip;
mmchip = devm_kzalloc(&pdev->dev, sizeof(*mmchip), GFP_KERNEL);
if (!mmchip)
return -ENOMEM;
/* Setup pointers to chip functions */
mmchip->gc.ngpio = (u16)(uintptr_t)of_id->data;
mmchip->gc.of_gpio_n_cells = 2;
mmchip->gc.direction_input = gef_gpio_dir_in;
mmchip->gc.direction_output = gef_gpio_dir_out;
mmchip->gc.get = gef_gpio_get;
mmchip->gc.set = gef_gpio_set;
/* This function adds a memory mapped GPIO chip */
return of_mm_gpiochip_add(pdev->dev.of_node, mmchip);
};
static struct platform_driver gef_gpio_driver = {
.driver = {
.name = "gef-gpio",
.owner = THIS_MODULE,
.of_match_table = gef_gpio_ids,
},
};
module_platform_driver_probe(gef_gpio_driver, gef_gpio_probe);
MODULE_DESCRIPTION("GE I/O FPGA GPIO driver");
MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");

Просмотреть файл

@ -388,6 +388,14 @@ static int bgpio_setup_direction(struct bgpio_chip *bgc,
return 0;
}
static int bgpio_request(struct gpio_chip *chip, unsigned gpio_pin)
{
if (gpio_pin < chip->ngpio)
return 0;
return -EINVAL;
}
int bgpio_remove(struct bgpio_chip *bgc)
{
return gpiochip_remove(&bgc->gc);
@ -413,6 +421,7 @@ int bgpio_init(struct bgpio_chip *bgc, struct device *dev,
bgc->gc.label = dev_name(dev);
bgc->gc.base = -1;
bgc->gc.ngpio = bgc->bits;
bgc->gc.request = bgpio_request;
ret = bgpio_setup_io(bgc, dat, set, clr);
if (ret)

Просмотреть файл

@ -481,7 +481,7 @@ out:
return ret;
}
static struct of_device_id grgpio_match[] = {
static const struct of_device_id grgpio_match[] = {
{.name = "GAISLER_GPIO"},
{.name = "01_01a"},
{},

Просмотреть файл

@ -152,34 +152,21 @@ static int ttl_probe(struct platform_device *pdev)
pdata = dev_get_platdata(&pdev->dev);
if (!pdata) {
dev_err(dev, "no platform data\n");
ret = -ENXIO;
goto out_return;
return -ENXIO;
}
mod = kzalloc(sizeof(*mod), GFP_KERNEL);
if (!mod) {
dev_err(dev, "unable to allocate private data\n");
ret = -ENOMEM;
goto out_return;
}
mod = devm_kzalloc(dev, sizeof(*mod), GFP_KERNEL);
if (!mod)
return -ENOMEM;
platform_set_drvdata(pdev, mod);
spin_lock_init(&mod->lock);
/* get access to the MODULbus registers for this module */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(dev, "MODULbus registers not found\n");
ret = -ENODEV;
goto out_free_mod;
}
mod->regs = ioremap(res->start, resource_size(res));
if (!mod->regs) {
dev_err(dev, "MODULbus registers not ioremap\n");
ret = -ENOMEM;
goto out_free_mod;
}
mod->regs = devm_ioremap_resource(dev, res);
if (IS_ERR(mod->regs))
return PTR_ERR(mod->regs);
ttl_setup_device(mod);
@ -198,17 +185,10 @@ static int ttl_probe(struct platform_device *pdev)
ret = gpiochip_add(gpio);
if (ret) {
dev_err(dev, "unable to add GPIO chip\n");
goto out_iounmap_regs;
return ret;
}
return 0;
out_iounmap_regs:
iounmap(mod->regs);
out_free_mod:
kfree(mod);
out_return:
return ret;
}
static int ttl_remove(struct platform_device *pdev)
@ -223,8 +203,6 @@ static int ttl_remove(struct platform_device *pdev)
return ret;
}
iounmap(mod->regs);
kfree(mod);
return 0;
}

Просмотреть файл

@ -24,7 +24,7 @@
#include <linux/mfd/kempld.h>
#define KEMPLD_GPIO_MAX_NUM 16
#define KEMPLD_GPIO_MASK(x) (1 << ((x) % 8))
#define KEMPLD_GPIO_MASK(x) (BIT((x) % 8))
#define KEMPLD_GPIO_DIR_NUM(x) (0x40 + (x) / 8)
#define KEMPLD_GPIO_LVL_NUM(x) (0x42 + (x) / 8)
#define KEMPLD_GPIO_EVT_LVL_EDGE 0x46
@ -216,4 +216,4 @@ module_platform_driver(kempld_gpio_driver);
MODULE_DESCRIPTION("KEM PLD GPIO Driver");
MODULE_AUTHOR("Michael Brunner <michael.brunner@kontron.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:gpio-kempld");
MODULE_ALIAS("platform:kempld-gpio");

Просмотреть файл

@ -375,10 +375,8 @@ static int lp_gpio_probe(struct platform_device *pdev)
int ret = -ENODEV;
lg = devm_kzalloc(dev, sizeof(struct lp_gpio), GFP_KERNEL);
if (!lg) {
dev_err(dev, "can't allocate lp_gpio chip data\n");
if (!lg)
return -ENOMEM;
}
lg->pdev = pdev;
platform_set_drvdata(pdev, lg);

Просмотреть файл

@ -237,10 +237,9 @@ int __max730x_remove(struct device *dev)
ts->write(dev, 0x04, 0x00);
ret = gpiochip_remove(&ts->chip);
if (!ret) {
if (!ret)
mutex_destroy(&ts->lock);
kfree(ts);
} else
else
dev_err(dev, "Failed to remove GPIO controller: %d\n", ret);
return ret;

Просмотреть файл

@ -714,7 +714,7 @@ fail:
#ifdef CONFIG_OF
#ifdef CONFIG_SPI_MASTER
static struct of_device_id mcp23s08_spi_of_match[] = {
static const struct of_device_id mcp23s08_spi_of_match[] = {
{
.compatible = "microchip,mcp23s08",
.data = (void *) MCP_TYPE_S08,
@ -738,7 +738,7 @@ MODULE_DEVICE_TABLE(of, mcp23s08_spi_of_match);
#endif
#if IS_ENABLED(CONFIG_I2C)
static struct of_device_id mcp23s08_i2c_of_match[] = {
static const struct of_device_id mcp23s08_i2c_of_match[] = {
{
.compatible = "microchip,mcp23008",
.data = (void *) MCP_TYPE_008,
@ -867,7 +867,7 @@ static int mcp23s08_probe(struct spi_device *spi)
{
struct mcp23s08_platform_data *pdata;
unsigned addr;
unsigned chips = 0;
int chips = 0;
struct mcp23s08_driver_data *data;
int status, type;
unsigned base = -1,
@ -894,11 +894,14 @@ static int mcp23s08_probe(struct spi_device *spi)
dev_err(&spi->dev, "invalid spi-present-mask\n");
return -ENODEV;
}
for (addr = 0; addr < ARRAY_SIZE(pdata->chip); addr++) {
if ((spi_present_mask & (1 << addr)))
chips++;
pullups[addr] = 0;
if (spi_present_mask & (1 << addr))
chips++;
}
if (!chips)
return -ENODEV;
} else {
type = spi_get_device_id(spi)->driver_data;
pdata = dev_get_platdata(&spi->dev);
@ -937,6 +940,10 @@ static int mcp23s08_probe(struct spi_device *spi)
if (!(spi_present_mask & (1 << addr)))
continue;
chips--;
if (chips < 0) {
dev_err(&spi->dev, "FATAL: invalid negative chip id\n");
goto fail;
}
data->mcp[addr] = &data->chip[chips];
status = mcp23s08_probe_one(data->mcp[addr], &spi->dev, spi,
0x40 | (addr << 1), type, base,

Просмотреть файл

@ -113,10 +113,8 @@ static int moxart_gpio_probe(struct platform_device *pdev)
int ret;
mgc = devm_kzalloc(dev, sizeof(*mgc), GFP_KERNEL);
if (!mgc) {
dev_err(dev, "can't allocate GPIO chip container\n");
if (!mgc)
return -ENOMEM;
}
mgc->gpio = moxart_template_chip;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

Просмотреть файл

@ -535,7 +535,7 @@ static void mvebu_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
#define mvebu_gpio_dbg_show NULL
#endif
static struct of_device_id mvebu_gpio_of_match[] = {
static const struct of_device_id mvebu_gpio_of_match[] = {
{
.compatible = "marvell,orion-gpio",
.data = (void *) MVEBU_GPIO_SOC_VARIANT_ORION,
@ -574,10 +574,8 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
soc_variant = MVEBU_GPIO_SOC_VARIANT_ORION;
mvchip = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_gpio_chip), GFP_KERNEL);
if (!mvchip) {
dev_err(&pdev->dev, "Cannot allocate memory\n");
if (!mvchip)
return -ENOMEM;
}
if (of_property_read_u32(pdev->dev.of_node, "ngpios", &ngpios)) {
dev_err(&pdev->dev, "Missing ngpios OF property\n");
@ -738,9 +736,4 @@ static struct platform_driver mvebu_gpio_driver = {
},
.probe = mvebu_gpio_probe,
};
static int __init mvebu_gpio_init(void)
{
return platform_driver_register(&mvebu_gpio_driver);
}
postcore_initcall(mvebu_gpio_init);
module_platform_driver(mvebu_gpio_driver);

Просмотреть файл

@ -24,9 +24,9 @@
#include <linux/pm.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/irqdomain.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/gpio.h>
#include <linux/bitops.h>
#include <linux/platform_data/gpio-omap.h>
#define OFF_MODE 1
@ -52,7 +52,6 @@ struct gpio_bank {
struct list_head node;
void __iomem *base;
u16 irq;
struct irq_domain *domain;
u32 non_wakeup_gpios;
u32 enabled_non_wakeup_gpios;
struct gpio_regs context;
@ -84,22 +83,21 @@ struct gpio_bank {
};
#define GPIO_INDEX(bank, gpio) (gpio % bank->width)
#define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio))
#define GPIO_BIT(bank, gpio) (BIT(GPIO_INDEX(bank, gpio)))
#define GPIO_MOD_CTRL_BIT BIT(0)
#define BANK_USED(bank) (bank->mod_usage || bank->irq_usage)
#define LINE_USED(line, offset) (line & (1 << offset))
#define LINE_USED(line, offset) (line & (BIT(offset)))
static int irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq)
{
return bank->chip.base + gpio_irq;
}
static int omap_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
static inline struct gpio_bank *_irq_data_get_bank(struct irq_data *d)
{
struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
return irq_find_mapping(bank->domain, offset);
struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
return container_of(chip, struct gpio_bank, chip);
}
static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
@ -110,9 +108,9 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
reg += bank->regs->direction;
l = readl_relaxed(reg);
if (is_input)
l |= 1 << gpio;
l |= BIT(gpio);
else
l &= ~(1 << gpio);
l &= ~(BIT(gpio));
writel_relaxed(l, reg);
bank->context.oe = l;
}
@ -155,14 +153,14 @@ static int _get_gpio_datain(struct gpio_bank *bank, int offset)
{
void __iomem *reg = bank->base + bank->regs->datain;
return (readl_relaxed(reg) & (1 << offset)) != 0;
return (readl_relaxed(reg) & (BIT(offset))) != 0;
}
static int _get_gpio_dataout(struct gpio_bank *bank, int offset)
{
void __iomem *reg = bank->base + bank->regs->dataout;
return (readl_relaxed(reg) & (1 << offset)) != 0;
return (readl_relaxed(reg) & (BIT(offset))) != 0;
}
static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set)
@ -180,7 +178,7 @@ static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set)
static inline void _gpio_dbck_enable(struct gpio_bank *bank)
{
if (bank->dbck_enable_mask && !bank->dbck_enabled) {
clk_enable(bank->dbck);
clk_prepare_enable(bank->dbck);
bank->dbck_enabled = true;
writel_relaxed(bank->dbck_enable_mask,
@ -198,7 +196,7 @@ static inline void _gpio_dbck_disable(struct gpio_bank *bank)
*/
writel_relaxed(0, bank->base + bank->regs->debounce_en);
clk_disable(bank->dbck);
clk_disable_unprepare(bank->dbck);
bank->dbck_enabled = false;
}
}
@ -231,7 +229,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
l = GPIO_BIT(bank, gpio);
clk_enable(bank->dbck);
clk_prepare_enable(bank->dbck);
reg = bank->base + bank->regs->debounce;
writel_relaxed(debounce, reg);
@ -245,7 +243,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
bank->dbck_enable_mask = val;
writel_relaxed(val, reg);
clk_disable(bank->dbck);
clk_disable_unprepare(bank->dbck);
/*
* Enable debounce clock per module.
* This call is mandatory because in omap_gpio_request() when
@ -290,7 +288,7 @@ static void _clear_gpio_debounce(struct gpio_bank *bank, unsigned gpio)
bank->context.debounce = 0;
writel_relaxed(bank->context.debounce, bank->base +
bank->regs->debounce);
clk_disable(bank->dbck);
clk_disable_unprepare(bank->dbck);
bank->dbck_enabled = false;
}
}
@ -299,7 +297,7 @@ static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio,
unsigned trigger)
{
void __iomem *base = bank->base;
u32 gpio_bit = 1 << gpio;
u32 gpio_bit = BIT(gpio);
_gpio_rmw(base, bank->regs->leveldetect0, gpio_bit,
trigger & IRQ_TYPE_LEVEL_LOW);
@ -368,9 +366,9 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
l = readl_relaxed(reg);
if ((l >> gpio) & 1)
l &= ~(1 << gpio);
l &= ~(BIT(gpio));
else
l |= 1 << gpio;
l |= BIT(gpio);
writel_relaxed(l, reg);
}
@ -392,11 +390,11 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio,
l = readl_relaxed(reg);
if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
bank->toggle_mask |= 1 << gpio;
bank->toggle_mask |= BIT(gpio);
if (trigger & IRQ_TYPE_EDGE_RISING)
l |= 1 << gpio;
l |= BIT(gpio);
else if (trigger & IRQ_TYPE_EDGE_FALLING)
l &= ~(1 << gpio);
l &= ~(BIT(gpio));
else
return -EINVAL;
@ -413,10 +411,10 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio,
if (trigger & IRQ_TYPE_EDGE_RISING)
l |= 2 << (gpio << 1);
if (trigger & IRQ_TYPE_EDGE_FALLING)
l |= 1 << (gpio << 1);
l |= BIT(gpio << 1);
/* Enable wake-up during idle for dynamic tick */
_gpio_rmw(base, bank->regs->wkup_en, 1 << gpio, trigger);
_gpio_rmw(base, bank->regs->wkup_en, BIT(gpio), trigger);
bank->context.wake_en =
readl_relaxed(bank->base + bank->regs->wkup_en);
writel_relaxed(l, reg);
@ -430,7 +428,7 @@ static void _enable_gpio_module(struct gpio_bank *bank, unsigned offset)
void __iomem *reg = bank->base + bank->regs->pinctrl;
/* Claim the pin for MPU */
writel_relaxed(readl_relaxed(reg) | (1 << offset), reg);
writel_relaxed(readl_relaxed(reg) | (BIT(offset)), reg);
}
if (bank->regs->ctrl && !BANK_USED(bank)) {
@ -453,7 +451,7 @@ static void _disable_gpio_module(struct gpio_bank *bank, unsigned offset)
!LINE_USED(bank->mod_usage, offset) &&
!LINE_USED(bank->irq_usage, offset)) {
/* Disable wake-up during idle for dynamic tick */
_gpio_rmw(base, bank->regs->wkup_en, 1 << offset, 0);
_gpio_rmw(base, bank->regs->wkup_en, BIT(offset), 0);
bank->context.wake_en =
readl_relaxed(bank->base + bank->regs->wkup_en);
}
@ -479,7 +477,7 @@ static int gpio_is_input(struct gpio_bank *bank, int mask)
static int gpio_irq_type(struct irq_data *d, unsigned type)
{
struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
struct gpio_bank *bank = _irq_data_get_bank(d);
unsigned gpio = 0;
int retval;
unsigned long flags;
@ -509,20 +507,12 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
if (!LINE_USED(bank->mod_usage, offset)) {
_enable_gpio_module(bank, offset);
_set_gpio_direction(bank, offset, 1);
} else if (!gpio_is_input(bank, 1 << offset)) {
} else if (!gpio_is_input(bank, BIT(offset))) {
spin_unlock_irqrestore(&bank->lock, flags);
return -EINVAL;
}
retval = gpio_lock_as_irq(&bank->chip, offset);
if (retval) {
dev_err(bank->dev, "unable to lock offset %d for IRQ\n",
offset);
spin_unlock_irqrestore(&bank->lock, flags);
return retval;
}
bank->irq_usage |= 1 << GPIO_INDEX(bank, gpio);
bank->irq_usage |= BIT(GPIO_INDEX(bank, gpio));
spin_unlock_irqrestore(&bank->lock, flags);
if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
@ -559,7 +549,7 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
{
void __iomem *reg = bank->base;
u32 l;
u32 mask = (1 << bank->width) - 1;
u32 mask = (BIT(bank->width)) - 1;
reg += bank->regs->irqenable;
l = readl_relaxed(reg);
@ -664,7 +654,7 @@ static void _reset_gpio(struct gpio_bank *bank, int gpio)
/* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
static int gpio_wake_enable(struct irq_data *d, unsigned int enable)
{
struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
struct gpio_bank *bank = _irq_data_get_bank(d);
unsigned int gpio = irq_to_gpio(bank, d->hwirq);
return _set_gpio_wakeup(bank, gpio, enable);
@ -691,7 +681,7 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
_enable_gpio_module(bank, offset);
}
bank->mod_usage |= 1 << offset;
bank->mod_usage |= BIT(offset);
spin_unlock_irqrestore(&bank->lock, flags);
return 0;
@ -703,7 +693,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
unsigned long flags;
spin_lock_irqsave(&bank->lock, flags);
bank->mod_usage &= ~(1 << offset);
bank->mod_usage &= ~(BIT(offset));
_disable_gpio_module(bank, offset);
_reset_gpio(bank, bank->chip.base + offset);
spin_unlock_irqrestore(&bank->lock, flags);
@ -732,11 +722,12 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
unsigned int bit;
struct gpio_bank *bank;
int unmasked = 0;
struct irq_chip *chip = irq_desc_get_chip(desc);
struct irq_chip *irqchip = irq_desc_get_chip(desc);
struct gpio_chip *chip = irq_get_handler_data(irq);
chained_irq_enter(chip, desc);
chained_irq_enter(irqchip, desc);
bank = irq_get_handler_data(irq);
bank = container_of(chip, struct gpio_bank, chip);
isr_reg = bank->base + bank->regs->irqstatus;
pm_runtime_get_sync(bank->dev);
@ -764,7 +755,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
configured, we could unmask GPIO bank interrupt immediately */
if (!level_mask && !unmasked) {
unmasked = 1;
chained_irq_exit(chip, desc);
chained_irq_exit(irqchip, desc);
}
if (!isr)
@ -772,7 +763,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
while (isr) {
bit = __ffs(isr);
isr &= ~(1 << bit);
isr &= ~(BIT(bit));
/*
* Some chips can't respond to both rising and falling
@ -781,10 +772,11 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
* to respond to the IRQ for the opposite direction.
* This will be indicated in the bank toggle_mask.
*/
if (bank->toggle_mask & (1 << bit))
if (bank->toggle_mask & (BIT(bit)))
_toggle_gpio_edge_triggering(bank, bit);
generic_handle_irq(irq_find_mapping(bank->domain, bit));
generic_handle_irq(irq_find_mapping(bank->chip.irqdomain,
bit));
}
}
/* if bank has any level sensitive GPIO pin interrupt
@ -793,20 +785,20 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
interrupt */
exit:
if (!unmasked)
chained_irq_exit(chip, desc);
chained_irq_exit(irqchip, desc);
pm_runtime_put(bank->dev);
}
static void gpio_irq_shutdown(struct irq_data *d)
{
struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
struct gpio_bank *bank = _irq_data_get_bank(d);
unsigned int gpio = irq_to_gpio(bank, d->hwirq);
unsigned long flags;
unsigned offset = GPIO_INDEX(bank, gpio);
spin_lock_irqsave(&bank->lock, flags);
gpio_unlock_as_irq(&bank->chip, offset);
bank->irq_usage &= ~(1 << offset);
bank->irq_usage &= ~(BIT(offset));
_disable_gpio_module(bank, offset);
_reset_gpio(bank, gpio);
spin_unlock_irqrestore(&bank->lock, flags);
@ -821,7 +813,7 @@ static void gpio_irq_shutdown(struct irq_data *d)
static void gpio_ack_irq(struct irq_data *d)
{
struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
struct gpio_bank *bank = _irq_data_get_bank(d);
unsigned int gpio = irq_to_gpio(bank, d->hwirq);
_clear_gpio_irqstatus(bank, gpio);
@ -829,7 +821,7 @@ static void gpio_ack_irq(struct irq_data *d)
static void gpio_mask_irq(struct irq_data *d)
{
struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
struct gpio_bank *bank = _irq_data_get_bank(d);
unsigned int gpio = irq_to_gpio(bank, d->hwirq);
unsigned long flags;
@ -841,7 +833,7 @@ static void gpio_mask_irq(struct irq_data *d)
static void gpio_unmask_irq(struct irq_data *d)
{
struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
struct gpio_bank *bank = _irq_data_get_bank(d);
unsigned int gpio = irq_to_gpio(bank, d->hwirq);
unsigned int irq_mask = GPIO_BIT(bank, gpio);
u32 trigger = irqd_get_trigger_type(d);
@ -936,6 +928,21 @@ static inline void mpuio_init(struct gpio_bank *bank)
/*---------------------------------------------------------------------*/
static int gpio_get_direction(struct gpio_chip *chip, unsigned offset)
{
struct gpio_bank *bank;
unsigned long flags;
void __iomem *reg;
int dir;
bank = container_of(chip, struct gpio_bank, chip);
reg = bank->base + bank->regs->direction;
spin_lock_irqsave(&bank->lock, flags);
dir = !!(readl_relaxed(reg) & BIT(offset));
spin_unlock_irqrestore(&bank->lock, flags);
return dir;
}
static int gpio_input(struct gpio_chip *chip, unsigned offset)
{
struct gpio_bank *bank;
@ -954,7 +961,7 @@ static int gpio_get(struct gpio_chip *chip, unsigned offset)
u32 mask;
bank = container_of(chip, struct gpio_bank, chip);
mask = (1 << offset);
mask = (BIT(offset));
if (gpio_is_input(bank, mask))
return _get_gpio_datain(bank, offset);
@ -1081,10 +1088,12 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start,
IRQ_NOREQUEST | IRQ_NOPROBE, 0);
}
static void omap_gpio_chip_init(struct gpio_bank *bank)
static int omap_gpio_chip_init(struct gpio_bank *bank)
{
int j;
static int gpio;
int irq_base = 0;
int ret;
/*
* REVISIT eventually switch from OMAP-specific gpio structs
@ -1092,12 +1101,12 @@ static void omap_gpio_chip_init(struct gpio_bank *bank)
*/
bank->chip.request = omap_gpio_request;
bank->chip.free = omap_gpio_free;
bank->chip.get_direction = gpio_get_direction;
bank->chip.direction_input = gpio_input;
bank->chip.get = gpio_get;
bank->chip.direction_output = gpio_output;
bank->chip.set_debounce = gpio_debounce;
bank->chip.set = gpio_set;
bank->chip.to_irq = omap_gpio_to_irq;
if (bank->is_mpuio) {
bank->chip.label = "mpuio";
if (bank->regs->wkup_en)
@ -1110,22 +1119,48 @@ static void omap_gpio_chip_init(struct gpio_bank *bank)
}
bank->chip.ngpio = bank->width;
gpiochip_add(&bank->chip);
ret = gpiochip_add(&bank->chip);
if (ret) {
dev_err(bank->dev, "Could not register gpio chip %d\n", ret);
return ret;
}
#ifdef CONFIG_ARCH_OMAP1
/*
* REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop
* irq_alloc_descs() since a base IRQ offset will no longer be needed.
*/
irq_base = irq_alloc_descs(-1, 0, bank->width, 0);
if (irq_base < 0) {
dev_err(bank->dev, "Couldn't allocate IRQ numbers\n");
return -ENODEV;
}
#endif
ret = gpiochip_irqchip_add(&bank->chip, &gpio_irq_chip,
irq_base, gpio_irq_handler,
IRQ_TYPE_NONE);
if (ret) {
dev_err(bank->dev, "Couldn't add irqchip to gpiochip %d\n", ret);
ret = gpiochip_remove(&bank->chip);
return -ENODEV;
}
gpiochip_set_chained_irqchip(&bank->chip, &gpio_irq_chip,
bank->irq, gpio_irq_handler);
for (j = 0; j < bank->width; j++) {
int irq = irq_create_mapping(bank->domain, j);
int irq = irq_find_mapping(bank->chip.irqdomain, j);
irq_set_lockdep_class(irq, &gpio_lock_class);
irq_set_chip_data(irq, bank);
if (bank->is_mpuio) {
omap_mpuio_alloc_gc(bank, irq, bank->width);
} else {
irq_set_chip_and_handler(irq, &gpio_irq_chip,
handle_simple_irq);
set_irq_flags(irq, IRQF_VALID);
irq_set_chip_and_handler(irq, NULL, NULL);
set_irq_flags(irq, 0);
}
}
irq_set_chained_handler(bank->irq, gpio_irq_handler);
irq_set_handler_data(bank->irq, bank);
return 0;
}
static const struct of_device_id omap_gpio_match[];
@ -1138,9 +1173,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
const struct omap_gpio_platform_data *pdata;
struct resource *res;
struct gpio_bank *bank;
#ifdef CONFIG_ARCH_OMAP1
int irq_base;
#endif
int ret;
match = of_match_device(of_match_ptr(omap_gpio_match), dev);
@ -1162,6 +1195,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
bank->irq = res->start;
bank->dev = dev;
bank->chip.dev = dev;
bank->dbck_flag = pdata->dbck_flag;
bank->stride = pdata->bank_stride;
bank->width = pdata->bank_width;
@ -1182,29 +1216,6 @@ static int omap_gpio_probe(struct platform_device *pdev)
pdata->get_context_loss_count;
}
#ifdef CONFIG_ARCH_OMAP1
/*
* REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop
* irq_alloc_descs() and irq_domain_add_legacy() and just use a
* linear IRQ domain mapping for all OMAP platforms.
*/
irq_base = irq_alloc_descs(-1, 0, bank->width, 0);
if (irq_base < 0) {
dev_err(dev, "Couldn't allocate IRQ numbers\n");
return -ENODEV;
}
bank->domain = irq_domain_add_legacy(node, bank->width, irq_base,
0, &irq_domain_simple_ops, NULL);
#else
bank->domain = irq_domain_add_linear(node, bank->width,
&irq_domain_simple_ops, NULL);
#endif
if (!bank->domain) {
dev_err(dev, "Couldn't register an IRQ domain\n");
return -ENODEV;
}
if (bank->regs->set_dataout && bank->regs->clr_dataout)
bank->set_dataout = _set_gpio_dataout_reg;
else
@ -1216,7 +1227,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
bank->base = devm_ioremap_resource(dev, res);
if (IS_ERR(bank->base)) {
irq_domain_remove(bank->domain);
irq_domain_remove(bank->chip.irqdomain);
return PTR_ERR(bank->base);
}
@ -1230,7 +1241,11 @@ static int omap_gpio_probe(struct platform_device *pdev)
mpuio_init(bank);
omap_gpio_mod_init(bank);
omap_gpio_chip_init(bank);
ret = omap_gpio_chip_init(bank);
if (ret)
return ret;
omap_gpio_show_rev(bank);
pm_runtime_put(bank->dev);

Просмотреть файл

@ -148,7 +148,7 @@ static const struct palmas_device_data tps80036_dev_data = {
.ngpio = 16,
};
static struct of_device_id of_palmas_gpio_match[] = {
static const struct of_device_id of_palmas_gpio_match[] = {
{ .compatible = "ti,palmas-gpio", .data = &palmas_dev_data,},
{ .compatible = "ti,tps65913-gpio", .data = &palmas_dev_data,},
{ .compatible = "ti,tps65914-gpio", .data = &palmas_dev_data,},
@ -173,10 +173,8 @@ static int palmas_gpio_probe(struct platform_device *pdev)
palmas_gpio = devm_kzalloc(&pdev->dev,
sizeof(*palmas_gpio), GFP_KERNEL);
if (!palmas_gpio) {
dev_err(&pdev->dev, "Could not allocate palmas_gpio\n");
if (!palmas_gpio)
return -ENOMEM;
}
palmas_gpio->palmas = palmas;
palmas_gpio->gpio_chip.owner = THIS_MODULE;

Просмотреть файл

@ -15,8 +15,6 @@
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/i2c.h>
#include <linux/platform_data/pca953x.h>
#include <linux/slab.h>
@ -91,7 +89,6 @@ struct pca953x_chip {
u8 irq_stat[MAX_BANK];
u8 irq_trig_raise[MAX_BANK];
u8 irq_trig_fall[MAX_BANK];
struct irq_domain *domain;
#endif
struct i2c_client *client;
@ -100,6 +97,11 @@ struct pca953x_chip {
int chip_type;
};
static inline struct pca953x_chip *to_pca(struct gpio_chip *gc)
{
return container_of(gc, struct pca953x_chip, gpio_chip);
}
static int pca953x_read_single(struct pca953x_chip *chip, int reg, u32 *val,
int off)
{
@ -202,12 +204,10 @@ static int pca953x_read_regs(struct pca953x_chip *chip, int reg, u8 *val)
static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
{
struct pca953x_chip *chip;
struct pca953x_chip *chip = to_pca(gc);
u8 reg_val;
int ret, offset = 0;
chip = container_of(gc, struct pca953x_chip, gpio_chip);
mutex_lock(&chip->i2c_lock);
reg_val = chip->reg_direction[off / BANK_SZ] | (1u << (off % BANK_SZ));
@ -233,12 +233,10 @@ exit:
static int pca953x_gpio_direction_output(struct gpio_chip *gc,
unsigned off, int val)
{
struct pca953x_chip *chip;
struct pca953x_chip *chip = to_pca(gc);
u8 reg_val;
int ret, offset = 0;
chip = container_of(gc, struct pca953x_chip, gpio_chip);
mutex_lock(&chip->i2c_lock);
/* set output level */
if (val)
@ -285,12 +283,10 @@ exit:
static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
{
struct pca953x_chip *chip;
struct pca953x_chip *chip = to_pca(gc);
u32 reg_val;
int ret, offset = 0;
chip = container_of(gc, struct pca953x_chip, gpio_chip);
mutex_lock(&chip->i2c_lock);
switch (chip->chip_type) {
case PCA953X_TYPE:
@ -315,12 +311,10 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
{
struct pca953x_chip *chip;
struct pca953x_chip *chip = to_pca(gc);
u8 reg_val;
int ret, offset = 0;
chip = container_of(gc, struct pca953x_chip, gpio_chip);
mutex_lock(&chip->i2c_lock);
if (val)
reg_val = chip->reg_output[off / BANK_SZ]
@ -367,38 +361,34 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
}
#ifdef CONFIG_GPIO_PCA953X_IRQ
static int pca953x_gpio_to_irq(struct gpio_chip *gc, unsigned off)
{
struct pca953x_chip *chip;
chip = container_of(gc, struct pca953x_chip, gpio_chip);
return irq_create_mapping(chip->domain, off);
}
static void pca953x_irq_mask(struct irq_data *d)
{
struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct pca953x_chip *chip = to_pca(gc);
chip->irq_mask[d->hwirq / BANK_SZ] &= ~(1 << (d->hwirq % BANK_SZ));
}
static void pca953x_irq_unmask(struct irq_data *d)
{
struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct pca953x_chip *chip = to_pca(gc);
chip->irq_mask[d->hwirq / BANK_SZ] |= 1 << (d->hwirq % BANK_SZ);
}
static void pca953x_irq_bus_lock(struct irq_data *d)
{
struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct pca953x_chip *chip = to_pca(gc);
mutex_lock(&chip->irq_lock);
}
static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
{
struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct pca953x_chip *chip = to_pca(gc);
u8 new_irqs;
int level, i;
@ -420,7 +410,8 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
static int pca953x_irq_set_type(struct irq_data *d, unsigned int type)
{
struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct pca953x_chip *chip = to_pca(gc);
int bank_nb = d->hwirq / BANK_SZ;
u8 mask = 1 << (d->hwirq % BANK_SZ);
@ -503,44 +494,25 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid)
struct pca953x_chip *chip = devid;
u8 pending[MAX_BANK];
u8 level;
unsigned nhandled = 0;
int i;
if (!pca953x_irq_pending(chip, pending))
return IRQ_HANDLED;
return IRQ_NONE;
for (i = 0; i < NBANK(chip); i++) {
while (pending[i]) {
level = __ffs(pending[i]);
handle_nested_irq(irq_find_mapping(chip->domain,
handle_nested_irq(irq_find_mapping(chip->gpio_chip.irqdomain,
level + (BANK_SZ * i)));
pending[i] &= ~(1 << level);
nhandled++;
}
}
return IRQ_HANDLED;
return (nhandled > 0) ? IRQ_HANDLED : IRQ_NONE;
}
static int pca953x_gpio_irq_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hwirq)
{
irq_clear_status_flags(irq, IRQ_NOREQUEST);
irq_set_chip_data(irq, d->host_data);
irq_set_chip(irq, &pca953x_irq_chip);
irq_set_nested_thread(irq, true);
#ifdef CONFIG_ARM
set_irq_flags(irq, IRQF_VALID);
#else
irq_set_noprobe(irq);
#endif
return 0;
}
static const struct irq_domain_ops pca953x_irq_simple_ops = {
.map = pca953x_gpio_irq_map,
.xlate = irq_domain_xlate_twocell,
};
static int pca953x_irq_setup(struct pca953x_chip *chip,
const struct i2c_device_id *id,
int irq_base)
@ -572,19 +544,12 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
chip->irq_stat[i] &= chip->reg_direction[i];
mutex_init(&chip->irq_lock);
chip->domain = irq_domain_add_simple(client->dev.of_node,
chip->gpio_chip.ngpio,
irq_base,
&pca953x_irq_simple_ops,
chip);
if (!chip->domain)
return -ENODEV;
ret = devm_request_threaded_irq(&client->dev,
client->irq,
NULL,
pca953x_irq_handler,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
IRQF_TRIGGER_LOW | IRQF_ONESHOT |
IRQF_SHARED,
dev_name(&client->dev), chip);
if (ret) {
dev_err(&client->dev, "failed to request irq %d\n",
@ -592,7 +557,16 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
return ret;
}
chip->gpio_chip.to_irq = pca953x_gpio_to_irq;
ret = gpiochip_irqchip_add(&chip->gpio_chip,
&pca953x_irq_chip,
irq_base,
handle_simple_irq,
IRQ_TYPE_NONE);
if (ret) {
dev_err(&client->dev,
"could not connect irqchip to gpiochip\n");
return ret;
}
}
return 0;
@ -756,11 +730,11 @@ static int pca953x_probe(struct i2c_client *client,
if (ret)
return ret;
ret = pca953x_irq_setup(chip, id, irq_base);
ret = gpiochip_add(&chip->gpio_chip);
if (ret)
return ret;
ret = gpiochip_add(&chip->gpio_chip);
ret = pca953x_irq_setup(chip, id, irq_base);
if (ret)
return ret;

Просмотреть файл

@ -262,7 +262,7 @@ static int pcf857x_irq_domain_init(struct pcf857x *gpio,
/* enable real irq */
status = devm_request_threaded_irq(&client->dev, client->irq,
NULL, pcf857x_irq, IRQF_ONESHOT |
IRQF_TRIGGER_FALLING,
IRQF_TRIGGER_FALLING | IRQF_SHARED,
dev_name(&client->dev), gpio);
if (status)
@ -319,7 +319,7 @@ static int pcf857x_probe(struct i2c_client *client,
status = pcf857x_irq_domain_init(gpio, client);
if (status < 0) {
dev_err(&client->dev, "irq_domain init failed\n");
goto fail;
goto fail_irq_domain;
}
}
@ -414,12 +414,13 @@ static int pcf857x_probe(struct i2c_client *client,
return 0;
fail:
dev_dbg(&client->dev, "probe error %d for '%s'\n",
status, client->name);
if (client->irq)
pcf857x_irq_domain_cleanup(gpio);
fail_irq_domain:
dev_dbg(&client->dev, "probe error %d for '%s'\n",
status, client->name);
return status;
}

Просмотреть файл

@ -20,6 +20,7 @@
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
#define PCH_EDGE_FALLING 0
#define PCH_EDGE_RISING BIT(0)

Просмотреть файл

@ -17,7 +17,6 @@
#include <linux/irq.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/bitops.h>
#include <linux/workqueue.h>
#include <linux/gpio.h>
#include <linux/device.h>
#include <linux/amba/bus.h>
@ -88,7 +87,7 @@ static int pl061_direction_input(struct gpio_chip *gc, unsigned offset)
spin_lock_irqsave(&chip->lock, flags);
gpiodir = readb(chip->base + GPIODIR);
gpiodir &= ~(1 << offset);
gpiodir &= ~(BIT(offset));
writeb(gpiodir, chip->base + GPIODIR);
spin_unlock_irqrestore(&chip->lock, flags);
@ -106,16 +105,16 @@ static int pl061_direction_output(struct gpio_chip *gc, unsigned offset,
return -EINVAL;
spin_lock_irqsave(&chip->lock, flags);
writeb(!!value << offset, chip->base + (1 << (offset + 2)));
writeb(!!value << offset, chip->base + (BIT(offset + 2)));
gpiodir = readb(chip->base + GPIODIR);
gpiodir |= 1 << offset;
gpiodir |= BIT(offset);
writeb(gpiodir, chip->base + GPIODIR);
/*
* gpio value is set again, because pl061 doesn't allow to set value of
* a gpio pin before configuring it in OUT mode.
*/
writeb(!!value << offset, chip->base + (1 << (offset + 2)));
writeb(!!value << offset, chip->base + (BIT(offset + 2)));
spin_unlock_irqrestore(&chip->lock, flags);
return 0;
@ -125,14 +124,14 @@ static int pl061_get_value(struct gpio_chip *gc, unsigned offset)
{
struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
return !!readb(chip->base + (1 << (offset + 2)));
return !!readb(chip->base + (BIT(offset + 2)));
}
static void pl061_set_value(struct gpio_chip *gc, unsigned offset, int value)
{
struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
writeb(!!value << offset, chip->base + (1 << (offset + 2)));
writeb(!!value << offset, chip->base + (BIT(offset + 2)));
}
static int pl061_irq_type(struct irq_data *d, unsigned trigger)
@ -207,7 +206,7 @@ static void pl061_irq_mask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
u8 mask = 1 << (irqd_to_hwirq(d) % PL061_GPIO_NR);
u8 mask = BIT(irqd_to_hwirq(d) % PL061_GPIO_NR);
u8 gpioie;
spin_lock(&chip->lock);
@ -220,7 +219,7 @@ static void pl061_irq_unmask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
u8 mask = 1 << (irqd_to_hwirq(d) % PL061_GPIO_NR);
u8 mask = BIT(irqd_to_hwirq(d) % PL061_GPIO_NR);
u8 gpioie;
spin_lock(&chip->lock);
@ -302,9 +301,9 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
for (i = 0; i < PL061_GPIO_NR; i++) {
if (pdata) {
if (pdata->directions & (1 << i))
if (pdata->directions & (BIT(i)))
pl061_direction_output(&chip->gc, i,
pdata->values & (1 << i));
pdata->values & (BIT(i)));
else
pl061_direction_input(&chip->gc, i);
}
@ -331,7 +330,7 @@ static int pl061_suspend(struct device *dev)
chip->csave_regs.gpio_ie = readb(chip->base + GPIOIE);
for (offset = 0; offset < PL061_GPIO_NR; offset++) {
if (chip->csave_regs.gpio_dir & (1 << offset))
if (chip->csave_regs.gpio_dir & (BIT(offset)))
chip->csave_regs.gpio_data |=
pl061_get_value(&chip->gc, offset) << offset;
}
@ -345,10 +344,10 @@ static int pl061_resume(struct device *dev)
int offset;
for (offset = 0; offset < PL061_GPIO_NR; offset++) {
if (chip->csave_regs.gpio_dir & (1 << offset))
if (chip->csave_regs.gpio_dir & (BIT(offset)))
pl061_direction_output(&chip->gc, offset,
chip->csave_regs.gpio_data &
(1 << offset));
(BIT(offset)));
else
pl061_direction_input(&chip->gc, offset);
}

Просмотреть файл

@ -119,10 +119,8 @@ static int rc5t583_gpio_probe(struct platform_device *pdev)
rc5t583_gpio = devm_kzalloc(&pdev->dev, sizeof(*rc5t583_gpio),
GFP_KERNEL);
if (!rc5t583_gpio) {
dev_warn(&pdev->dev, "Mem allocation for rc5t583_gpio failed");
if (!rc5t583_gpio)
return -ENOMEM;
}
rc5t583_gpio->gpio_chip.label = "gpio-rc5t583",
rc5t583_gpio->gpio_chip.owner = THIS_MODULE,

Просмотреть файл

@ -26,6 +26,7 @@
#include <linux/pinctrl/consumer.h>
#include <linux/platform_data/gpio-rcar.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
@ -362,7 +363,6 @@ static int gpio_rcar_probe(struct platform_device *pdev)
p = devm_kzalloc(dev, sizeof(*p), GFP_KERNEL);
if (!p) {
dev_err(dev, "failed to allocate driver data\n");
ret = -ENOMEM;
goto err0;
}
@ -377,6 +377,9 @@ static int gpio_rcar_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, p);
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@ -460,6 +463,8 @@ static int gpio_rcar_probe(struct platform_device *pdev)
err1:
irq_domain_remove(p->irq_domain);
err0:
pm_runtime_put(dev);
pm_runtime_disable(dev);
return ret;
}
@ -473,6 +478,8 @@ static int gpio_rcar_remove(struct platform_device *pdev)
return ret;
irq_domain_remove(p->irq_domain);
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return 0;
}

Просмотреть файл

@ -141,17 +141,15 @@ static int rdc321x_gpio_probe(struct platform_device *pdev)
return -ENODEV;
}
rdc321x_gpio_dev = kzalloc(sizeof(struct rdc321x_gpio), GFP_KERNEL);
if (!rdc321x_gpio_dev) {
dev_err(&pdev->dev, "failed to allocate private data\n");
rdc321x_gpio_dev = devm_kzalloc(&pdev->dev, sizeof(struct rdc321x_gpio),
GFP_KERNEL);
if (!rdc321x_gpio_dev)
return -ENOMEM;
}
r = platform_get_resource_byname(pdev, IORESOURCE_IO, "gpio-reg1");
if (!r) {
dev_err(&pdev->dev, "failed to get gpio-reg1 resource\n");
err = -ENODEV;
goto out_free;
return -ENODEV;
}
spin_lock_init(&rdc321x_gpio_dev->lock);
@ -162,8 +160,7 @@ static int rdc321x_gpio_probe(struct platform_device *pdev)
r = platform_get_resource_byname(pdev, IORESOURCE_IO, "gpio-reg2");
if (!r) {
dev_err(&pdev->dev, "failed to get gpio-reg2 resource\n");
err = -ENODEV;
goto out_free;
return -ENODEV;
}
rdc321x_gpio_dev->reg2_ctrl_base = r->start;
@ -187,21 +184,17 @@ static int rdc321x_gpio_probe(struct platform_device *pdev)
rdc321x_gpio_dev->reg1_data_base,
&rdc321x_gpio_dev->data_reg[0]);
if (err)
goto out_free;
return err;
err = pci_read_config_dword(rdc321x_gpio_dev->sb_pdev,
rdc321x_gpio_dev->reg2_data_base,
&rdc321x_gpio_dev->data_reg[1]);
if (err)
goto out_free;
return err;
dev_info(&pdev->dev, "registering %d GPIOs\n",
rdc321x_gpio_dev->chip.ngpio);
return gpiochip_add(&rdc321x_gpio_dev->chip);
out_free:
kfree(rdc321x_gpio_dev);
return err;
}
static int rdc321x_gpio_remove(struct platform_device *pdev)
@ -213,8 +206,6 @@ static int rdc321x_gpio_remove(struct platform_device *pdev)
if (ret)
dev_err(&pdev->dev, "failed to unregister chip\n");
kfree(rdc321x_gpio_dev);
return ret;
}

Просмотреть файл

@ -97,8 +97,6 @@ static int sch_gpio_core_direction_out(struct gpio_chip *gc,
u8 curr_dirs;
unsigned short offset, bit;
sch_gpio_core_set(gc, gpio_num, val);
spin_lock(&gpio_lock);
offset = CGIO + gpio_num / 8;
@ -109,6 +107,17 @@ static int sch_gpio_core_direction_out(struct gpio_chip *gc,
outb(curr_dirs & ~(1 << bit), gpio_ba + offset);
spin_unlock(&gpio_lock);
/*
* according to the datasheet, writing to the level register has no
* effect when GPIO is programmed as input.
* Actually the the level register is read-only when configured as input.
* Thus presetting the output level before switching to output is _NOT_ possible.
* Hence we set the level after configuring the GPIO as output.
* But we cannot prevent a short low pulse if direction is set to high
* and an external pull-up is connected.
*/
sch_gpio_core_set(gc, gpio_num, val);
return 0;
}
@ -178,8 +187,6 @@ static int sch_gpio_resume_direction_out(struct gpio_chip *gc,
u8 curr_dirs;
unsigned short offset, bit;
sch_gpio_resume_set(gc, gpio_num, val);
offset = RGIO + gpio_num / 8;
bit = gpio_num % 8;
@ -190,6 +197,17 @@ static int sch_gpio_resume_direction_out(struct gpio_chip *gc,
outb(curr_dirs & ~(1 << bit), gpio_ba + offset);
spin_unlock(&gpio_lock);
/*
* according to the datasheet, writing to the level register has no
* effect when GPIO is programmed as input.
* Actually the the level register is read-only when configured as input.
* Thus presetting the output level before switching to output is _NOT_ possible.
* Hence we set the level after configuring the GPIO as output.
* But we cannot prevent a short low pulse if direction is set to high
* and an external pull-up is connected.
*/
sch_gpio_resume_set(gc, gpio_num, val);
return 0;
}

Просмотреть файл

@ -327,14 +327,22 @@ static int __init sch311x_detect(int sio_config_port, unsigned short *addr)
if (err)
return err;
/* Check device ID. We currently know about:
* SCH3112 (0x7c), SCH3114 (0x7d), and SCH3116 (0x7f). */
/* Check device ID. */
reg = sch311x_sio_inb(sio_config_port, 0x20);
if (!(reg == 0x7c || reg == 0x7d || reg == 0x7f)) {
switch (reg) {
case 0x7c: /* SCH3112 */
dev_id = 2;
break;
case 0x7d: /* SCH3114 */
dev_id = 4;
break;
case 0x7f: /* SCH3116 */
dev_id = 6;
break;
default:
err = -ENODEV;
goto exit;
}
dev_id = reg == 0x7c ? 2 : reg == 0x7d ? 4 : 6;
/* Select logical device A (runtime registers) */
sch311x_sio_outb(sio_config_port, 0x07, 0x0a);

Просмотреть файл

@ -129,10 +129,8 @@ static int spics_gpio_probe(struct platform_device *pdev)
int ret;
spics = devm_kzalloc(&pdev->dev, sizeof(*spics), GFP_KERNEL);
if (!spics) {
dev_err(&pdev->dev, "memory allocation fail\n");
if (!spics)
return -ENOMEM;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
spics->base = devm_ioremap_resource(&pdev->dev, res);

Просмотреть файл

@ -22,7 +22,6 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/i2c/sx150x.h>
#define NO_UPDATE_PENDING -1

Просмотреть файл

@ -12,8 +12,6 @@
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/interrupt.h>
#include <linux/mfd/tc3589x.h>
@ -31,10 +29,6 @@ struct tc3589x_gpio {
struct tc3589x *tc3589x;
struct device *dev;
struct mutex irq_lock;
struct irq_domain *domain;
int irq_base;
/* Caches of interrupt control registers for bus_lock */
u8 regs[CACHE_NR_REGS][CACHE_NR_BANKS];
u8 oldregs[CACHE_NR_REGS][CACHE_NR_BANKS];
@ -95,30 +89,6 @@ static int tc3589x_gpio_direction_input(struct gpio_chip *chip,
return tc3589x_set_bits(tc3589x, reg, 1 << pos, 0);
}
/**
* tc3589x_gpio_irq_get_irq(): Map a hardware IRQ on a chip to a Linux IRQ
*
* @tc3589x_gpio: tc3589x_gpio_irq controller to operate on.
* @irq: index of the hardware interrupt requested in the chip IRQs
*
* Useful for drivers to request their own IRQs.
*/
static int tc3589x_gpio_irq_get_irq(struct tc3589x_gpio *tc3589x_gpio,
int hwirq)
{
if (!tc3589x_gpio)
return -EINVAL;
return irq_create_mapping(tc3589x_gpio->domain, hwirq);
}
static int tc3589x_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct tc3589x_gpio *tc3589x_gpio = to_tc3589x_gpio(chip);
return tc3589x_gpio_irq_get_irq(tc3589x_gpio, offset);
}
static struct gpio_chip template_chip = {
.label = "tc3589x",
.owner = THIS_MODULE,
@ -126,13 +96,13 @@ static struct gpio_chip template_chip = {
.get = tc3589x_gpio_get,
.direction_output = tc3589x_gpio_direction_output,
.set = tc3589x_gpio_set,
.to_irq = tc3589x_gpio_to_irq,
.can_sleep = true,
};
static int tc3589x_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{
struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct tc3589x_gpio *tc3589x_gpio = container_of(gc, struct tc3589x_gpio, chip);
int offset = d->hwirq;
int regoffset = offset / 8;
int mask = 1 << (offset % 8);
@ -159,14 +129,16 @@ static int tc3589x_gpio_irq_set_type(struct irq_data *d, unsigned int type)
static void tc3589x_gpio_irq_lock(struct irq_data *d)
{
struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct tc3589x_gpio *tc3589x_gpio = container_of(gc, struct tc3589x_gpio, chip);
mutex_lock(&tc3589x_gpio->irq_lock);
}
static void tc3589x_gpio_irq_sync_unlock(struct irq_data *d)
{
struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct tc3589x_gpio *tc3589x_gpio = container_of(gc, struct tc3589x_gpio, chip);
struct tc3589x *tc3589x = tc3589x_gpio->tc3589x;
static const u8 regmap[] = {
[REG_IBE] = TC3589x_GPIOIBE0,
@ -194,7 +166,8 @@ static void tc3589x_gpio_irq_sync_unlock(struct irq_data *d)
static void tc3589x_gpio_irq_mask(struct irq_data *d)
{
struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct tc3589x_gpio *tc3589x_gpio = container_of(gc, struct tc3589x_gpio, chip);
int offset = d->hwirq;
int regoffset = offset / 8;
int mask = 1 << (offset % 8);
@ -204,7 +177,8 @@ static void tc3589x_gpio_irq_mask(struct irq_data *d)
static void tc3589x_gpio_irq_unmask(struct irq_data *d)
{
struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct tc3589x_gpio *tc3589x_gpio = container_of(gc, struct tc3589x_gpio, chip);
int offset = d->hwirq;
int regoffset = offset / 8;
int mask = 1 << (offset % 8);
@ -242,7 +216,8 @@ static irqreturn_t tc3589x_gpio_irq(int irq, void *dev)
while (stat) {
int bit = __ffs(stat);
int line = i * 8 + bit;
int irq = tc3589x_gpio_irq_get_irq(tc3589x_gpio, line);
int irq = irq_find_mapping(tc3589x_gpio->chip.irqdomain,
line);
handle_nested_irq(irq);
stat &= ~(1 << bit);
@ -254,61 +229,6 @@ static irqreturn_t tc3589x_gpio_irq(int irq, void *dev)
return IRQ_HANDLED;
}
static int tc3589x_gpio_irq_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hwirq)
{
struct tc3589x *tc3589x_gpio = d->host_data;
irq_set_chip_data(irq, tc3589x_gpio);
irq_set_chip_and_handler(irq, &tc3589x_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 tc3589x_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 struct irq_domain_ops tc3589x_irq_ops = {
.map = tc3589x_gpio_irq_map,
.unmap = tc3589x_gpio_irq_unmap,
.xlate = irq_domain_xlate_twocell,
};
static int tc3589x_gpio_irq_init(struct tc3589x_gpio *tc3589x_gpio,
struct device_node *np)
{
int base = tc3589x_gpio->irq_base;
/*
* If this results in a linear domain, irq_create_mapping() will
* take care of allocating IRQ descriptors at runtime. When a base
* is provided, the IRQ descriptors will be allocated when the
* domain is instantiated.
*/
tc3589x_gpio->domain = irq_domain_add_simple(np,
tc3589x_gpio->chip.ngpio, base, &tc3589x_irq_ops,
tc3589x_gpio);
if (!tc3589x_gpio->domain) {
dev_err(tc3589x_gpio->dev, "Failed to create irqdomain\n");
return -ENOSYS;
}
return 0;
}
static int tc3589x_gpio_probe(struct platform_device *pdev)
{
struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent);
@ -329,7 +249,8 @@ static int tc3589x_gpio_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
tc3589x_gpio = kzalloc(sizeof(struct tc3589x_gpio), GFP_KERNEL);
tc3589x_gpio = devm_kzalloc(&pdev->dev, sizeof(struct tc3589x_gpio),
GFP_KERNEL);
if (!tc3589x_gpio)
return -ENOMEM;
@ -347,30 +268,36 @@ static int tc3589x_gpio_probe(struct platform_device *pdev)
tc3589x_gpio->chip.of_node = np;
#endif
tc3589x_gpio->irq_base = tc3589x->irq_base ?
tc3589x->irq_base + TC3589x_INT_GPIO(0) : 0;
/* Bring the GPIO module out of reset */
ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL,
TC3589x_RSTCTRL_GPIRST, 0);
if (ret < 0)
goto out_free;
return ret;
ret = tc3589x_gpio_irq_init(tc3589x_gpio, np);
if (ret)
goto out_free;
ret = request_threaded_irq(irq, NULL, tc3589x_gpio_irq, IRQF_ONESHOT,
"tc3589x-gpio", tc3589x_gpio);
ret = devm_request_threaded_irq(&pdev->dev,
irq, NULL, tc3589x_gpio_irq,
IRQF_ONESHOT, "tc3589x-gpio",
tc3589x_gpio);
if (ret) {
dev_err(&pdev->dev, "unable to get irq: %d\n", ret);
goto out_free;
return ret;
}
ret = gpiochip_add(&tc3589x_gpio->chip);
if (ret) {
dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret);
goto out_freeirq;
return ret;
}
ret = gpiochip_irqchip_add(&tc3589x_gpio->chip,
&tc3589x_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;
}
if (pdata && pdata->setup)
@ -379,12 +306,6 @@ static int tc3589x_gpio_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, tc3589x_gpio);
return 0;
out_freeirq:
free_irq(irq, tc3589x_gpio);
out_free:
kfree(tc3589x_gpio);
return ret;
}
static int tc3589x_gpio_remove(struct platform_device *pdev)
@ -392,7 +313,6 @@ static int tc3589x_gpio_remove(struct platform_device *pdev)
struct tc3589x_gpio *tc3589x_gpio = platform_get_drvdata(pdev);
struct tc3589x *tc3589x = tc3589x_gpio->tc3589x;
struct tc3589x_gpio_platform_data *pdata = tc3589x->pdata->gpio;
int irq = platform_get_irq(pdev, 0);
int ret;
if (pdata && pdata->remove)
@ -405,10 +325,6 @@ static int tc3589x_gpio_remove(struct platform_device *pdev)
return ret;
}
free_irq(irq, tc3589x_gpio);
kfree(tc3589x_gpio);
return 0;
}

Просмотреть файл

@ -408,7 +408,7 @@ static struct tegra_gpio_soc_config tegra30_gpio_config = {
.upper_offset = 0x80,
};
static struct of_device_id tegra_gpio_of_match[] = {
static const struct of_device_id tegra_gpio_of_match[] = {
{ .compatible = "nvidia,tegra30-gpio", .data = &tegra30_gpio_config },
{ .compatible = "nvidia,tegra20-gpio", .data = &tegra20_gpio_config },
{ },
@ -458,10 +458,8 @@ static int tegra_gpio_probe(struct platform_device *pdev)
tegra_gpio_banks = devm_kzalloc(&pdev->dev,
tegra_gpio_bank_count * sizeof(*tegra_gpio_banks),
GFP_KERNEL);
if (!tegra_gpio_banks) {
dev_err(&pdev->dev, "Couldn't allocate bank structure\n");
if (!tegra_gpio_banks)
return -ENODEV;
}
irq_domain = irq_domain_add_linear(pdev->dev.of_node,
tegra_gpio_chip.ngpio,

Просмотреть файл

@ -224,6 +224,7 @@ static struct irq_chip timbgpio_irqchip = {
static int timbgpio_probe(struct platform_device *pdev)
{
int err, i;
struct device *dev = &pdev->dev;
struct gpio_chip *gc;
struct timbgpio *tgpio;
struct resource *iomem;
@ -231,35 +232,35 @@ static int timbgpio_probe(struct platform_device *pdev)
int irq = platform_get_irq(pdev, 0);
if (!pdata || pdata->nr_pins > 32) {
err = -EINVAL;
goto err_mem;
dev_err(dev, "Invalid platform data\n");
return -EINVAL;
}
iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!iomem) {
err = -EINVAL;
goto err_mem;
dev_err(dev, "Unable to get resource\n");
return -EINVAL;
}
tgpio = kzalloc(sizeof(*tgpio), GFP_KERNEL);
tgpio = devm_kzalloc(dev, sizeof(struct timbgpio), GFP_KERNEL);
if (!tgpio) {
err = -EINVAL;
goto err_mem;
dev_err(dev, "Memory alloc failed\n");
return -EINVAL;
}
tgpio->irq_base = pdata->irq_base;
spin_lock_init(&tgpio->lock);
if (!request_mem_region(iomem->start, resource_size(iomem),
DRIVER_NAME)) {
err = -EBUSY;
goto err_request;
if (!devm_request_mem_region(dev, iomem->start, resource_size(iomem),
DRIVER_NAME)) {
dev_err(dev, "Region already claimed\n");
return -EBUSY;
}
tgpio->membase = ioremap(iomem->start, resource_size(iomem));
tgpio->membase = devm_ioremap(dev, iomem->start, resource_size(iomem));
if (!tgpio->membase) {
err = -ENOMEM;
goto err_ioremap;
dev_err(dev, "Cannot ioremap\n");
return -ENOMEM;
}
gc = &tgpio->gpio;
@ -279,7 +280,7 @@ static int timbgpio_probe(struct platform_device *pdev)
err = gpiochip_add(gc);
if (err)
goto err_chipadd;
return err;
platform_set_drvdata(pdev, tgpio);
@ -302,17 +303,6 @@ static int timbgpio_probe(struct platform_device *pdev)
irq_set_chained_handler(irq, timbgpio_irq);
return 0;
err_chipadd:
iounmap(tgpio->membase);
err_ioremap:
release_mem_region(iomem->start, resource_size(iomem));
err_request:
kfree(tgpio);
err_mem:
printk(KERN_ERR DRIVER_NAME": Failed to register GPIOs: %d\n", err);
return err;
}
static int timbgpio_remove(struct platform_device *pdev)
@ -320,7 +310,6 @@ static int timbgpio_remove(struct platform_device *pdev)
int err;
struct timbgpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct timbgpio *tgpio = platform_get_drvdata(pdev);
struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
int irq = platform_get_irq(pdev, 0);
if (irq >= 0 && tgpio->irq_base > 0) {
@ -338,10 +327,6 @@ static int timbgpio_remove(struct platform_device *pdev)
if (err)
printk(KERN_ERR DRIVER_NAME": failed to remove gpio_chip\n");
iounmap(tgpio->membase);
release_mem_region(iomem->start, resource_size(iomem));
kfree(tgpio);
return 0;
}

Просмотреть файл

@ -97,10 +97,8 @@ static int tps6586x_gpio_probe(struct platform_device *pdev)
pdata = dev_get_platdata(pdev->dev.parent);
tps6586x_gpio = devm_kzalloc(&pdev->dev,
sizeof(*tps6586x_gpio), GFP_KERNEL);
if (!tps6586x_gpio) {
dev_err(&pdev->dev, "Could not allocate tps6586x_gpio\n");
if (!tps6586x_gpio)
return -ENOMEM;
}
tps6586x_gpio->parent = pdev->dev.parent;

Просмотреть файл

@ -123,10 +123,8 @@ static int tps65910_gpio_probe(struct platform_device *pdev)
tps65910_gpio = devm_kzalloc(&pdev->dev,
sizeof(*tps65910_gpio), GFP_KERNEL);
if (!tps65910_gpio) {
dev_err(&pdev->dev, "Could not allocate tps65910_gpio\n");
if (!tps65910_gpio)
return -ENOMEM;
}
tps65910_gpio->tps65910 = tps65910;

Просмотреть файл

@ -289,7 +289,7 @@ static int xgpio_of_probe(struct device_node *np)
return 0;
}
static struct of_device_id xgpio_of_match[] = {
static const struct of_device_id xgpio_of_match[] = {
{ .compatible = "xlnx,xps-gpio-1.00.a", },
{ /* end of list */ },
};

Просмотреть файл

@ -81,9 +81,15 @@ static inline void zevio_gpio_port_set(struct zevio_gpio *c, unsigned pin,
static int zevio_gpio_get(struct gpio_chip *chip, unsigned pin)
{
struct zevio_gpio *controller = to_zevio_gpio(chip);
u32 val, dir;
/* Only reading allowed, so no spinlock needed */
u32 val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_INPUT);
spin_lock(&controller->lock);
dir = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_DIRECTION);
if (dir & BIT(ZEVIO_GPIO_BIT(pin)))
val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_INPUT);
else
val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_OUTPUT);
spin_unlock(&controller->lock);
return (val >> ZEVIO_GPIO_BIT(pin)) & 0x1;
}
@ -172,10 +178,8 @@ static int zevio_gpio_probe(struct platform_device *pdev)
int status, i;
controller = devm_kzalloc(&pdev->dev, sizeof(*controller), GFP_KERNEL);
if (!controller) {
dev_err(&pdev->dev, "not enough free memory\n");
if (!controller)
return -ENOMEM;
}
/* Copy our reference */
controller->chip.gc = zevio_gpio_chip;
@ -198,7 +202,7 @@ static int zevio_gpio_probe(struct platform_device *pdev)
return 0;
}
static struct of_device_id zevio_gpio_of_match[] = {
static const struct of_device_id zevio_gpio_of_match[] = {
{ .compatible = "lsi,zevio-gpio", },
{ },
};
@ -209,7 +213,7 @@ static struct platform_driver zevio_gpio_driver = {
.driver = {
.name = "gpio-zevio",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(zevio_gpio_of_match),
.of_match_table = zevio_gpio_of_match,
},
.probe = zevio_gpio_probe,
};

Просмотреть файл

@ -449,9 +449,10 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
mutex_unlock(&achip->conn_lock);
if (function == ACPI_WRITE)
gpiod_set_raw_value(desc, !!((1 << i) & *value));
gpiod_set_raw_value_cansleep(desc,
!!((1 << i) & *value));
else
*value |= (u64)gpiod_get_raw_value(desc) << i;
*value |= (u64)gpiod_get_raw_value_cansleep(desc) << i;
}
out:

Просмотреть файл

@ -48,7 +48,7 @@ static int of_gpiochip_find_and_xlate(struct gpio_chip *gc, void *data)
if (ret < 0)
return false;
gg_data->out_gpio = gpio_to_desc(ret + gc->base);
gg_data->out_gpio = gpiochip_get_desc(gc, ret);
return true;
}
@ -96,6 +96,20 @@ struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
}
EXPORT_SYMBOL(of_get_named_gpiod_flags);
int of_get_named_gpio_flags(struct device_node *np, const char *list_name,
int index, enum of_gpio_flags *flags)
{
struct gpio_desc *desc;
desc = of_get_named_gpiod_flags(np, list_name, index, flags);
if (IS_ERR(desc))
return PTR_ERR(desc);
else
return desc_to_gpio(desc);
}
EXPORT_SYMBOL(of_get_named_gpio_flags);
/**
* of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags
* @gc: pointer to the gpio_chip structure

Просмотреть файл

@ -1363,6 +1363,11 @@ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,
int parent_irq,
irq_flow_handler_t parent_handler)
{
if (gpiochip->can_sleep) {
chip_err(gpiochip, "you cannot have chained interrupts on a chip that may sleep\n");
return;
}
irq_set_chained_handler(parent_irq, parent_handler);
/*
* The parent irqchip is already using the chip_data for this
@ -1372,6 +1377,12 @@ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,
}
EXPORT_SYMBOL_GPL(gpiochip_set_chained_irqchip);
/*
* This lock class tells lockdep that GPIO irqs are in a different
* category than their parents, so it won't report false recursion.
*/
static struct lock_class_key gpiochip_irq_lock_class;
/**
* gpiochip_irq_map() - maps an IRQ into a GPIO irqchip
* @d: the irqdomain used by this irqchip
@ -1388,22 +1399,35 @@ static int gpiochip_irq_map(struct irq_domain *d, unsigned int irq,
struct gpio_chip *chip = d->host_data;
irq_set_chip_data(irq, chip);
irq_set_lockdep_class(irq, &gpiochip_irq_lock_class);
irq_set_chip_and_handler(irq, chip->irqchip, chip->irq_handler);
/* Chips that can sleep need nested thread handlers */
if (chip->can_sleep)
irq_set_nested_thread(irq, 1);
#ifdef CONFIG_ARM
set_irq_flags(irq, IRQF_VALID);
#else
irq_set_noprobe(irq);
#endif
irq_set_irq_type(irq, chip->irq_default_type);
/*
* No set-up of the hardware will happen if IRQ_TYPE_NONE
* is passed as default type.
*/
if (chip->irq_default_type != IRQ_TYPE_NONE)
irq_set_irq_type(irq, chip->irq_default_type);
return 0;
}
static void gpiochip_irq_unmap(struct irq_domain *d, unsigned int irq)
{
struct gpio_chip *chip = d->host_data;
#ifdef CONFIG_ARM
set_irq_flags(irq, 0);
#endif
if (chip->can_sleep)
irq_set_nested_thread(irq, 0);
irq_set_chip_and_handler(irq, NULL, NULL);
irq_set_chip_data(irq, NULL);
}
@ -1471,7 +1495,8 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip)
* @first_irq: if not dynamically assigned, the base (first) IRQ to
* allocate gpiochip irqs from
* @handler: the irq handler to use (often a predefined irq core function)
* @type: the default type for IRQs on this irqchip
* @type: the default type for IRQs on this irqchip, pass IRQ_TYPE_NONE
* to have the core avoid setting up any default type in the hardware.
*
* This function closely associates a certain irqchip with a certain
* gpiochip, providing an irq domain to translate the local IRQs to
@ -2571,22 +2596,27 @@ void gpiod_add_lookup_table(struct gpiod_lookup_table *table)
mutex_unlock(&gpio_lookup_lock);
}
#ifdef CONFIG_OF
static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
unsigned int idx,
enum gpio_lookup_flags *flags)
{
static const char *suffixes[] = { "gpios", "gpio" };
char prop_name[32]; /* 32 is max size of property name */
enum of_gpio_flags of_flags;
struct gpio_desc *desc;
unsigned int i;
if (con_id)
snprintf(prop_name, 32, "%s-gpios", con_id);
else
snprintf(prop_name, 32, "gpios");
for (i = 0; i < ARRAY_SIZE(suffixes); i++) {
if (con_id)
snprintf(prop_name, 32, "%s-%s", con_id, suffixes[i]);
else
snprintf(prop_name, 32, "%s", suffixes[i]);
desc = of_get_named_gpiod_flags(dev->of_node, prop_name, idx,
&of_flags);
desc = of_get_named_gpiod_flags(dev->of_node, prop_name, idx,
&of_flags);
if (!IS_ERR(desc))
break;
}
if (IS_ERR(desc))
return desc;
@ -2596,14 +2626,6 @@ static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
return desc;
}
#else
static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
unsigned int idx,
enum gpio_lookup_flags *flags)
{
return ERR_PTR(-ENODEV);
}
#endif
static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id,
unsigned int idx,
@ -2701,7 +2723,7 @@ static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id,
}
/**
* gpio_get - obtain a GPIO for a given GPIO function
* gpiod_get - obtain a GPIO for a given GPIO function
* @dev: GPIO consumer, can be NULL for system-global GPIOs
* @con_id: function within the GPIO consumer
*
@ -2715,6 +2737,22 @@ struct gpio_desc *__must_check gpiod_get(struct device *dev, const char *con_id)
}
EXPORT_SYMBOL_GPL(gpiod_get);
/**
* gpiod_get_optional - obtain an optional GPIO for a given GPIO function
* @dev: GPIO consumer, can be NULL for system-global GPIOs
* @con_id: function within the GPIO consumer
*
* This is equivalent to gpiod_get(), except that when no GPIO was assigned to
* the requested function it will return NULL. This is convenient for drivers
* that need to handle optional GPIOs.
*/
struct gpio_desc *__must_check gpiod_get_optional(struct device *dev,
const char *con_id)
{
return gpiod_get_index_optional(dev, con_id, 0);
}
EXPORT_SYMBOL_GPL(gpiod_get_optional);
/**
* gpiod_get_index - obtain a GPIO from a multi-index GPIO function
* @dev: GPIO consumer, can be NULL for system-global GPIOs
@ -2777,6 +2815,33 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
}
EXPORT_SYMBOL_GPL(gpiod_get_index);
/**
* gpiod_get_index_optional - obtain an optional GPIO from a multi-index GPIO
* function
* @dev: GPIO consumer, can be NULL for system-global GPIOs
* @con_id: function within the GPIO consumer
* @index: index of the GPIO to obtain in the consumer
*
* This is equivalent to gpiod_get_index(), except that when no GPIO with the
* specified index was assigned to the requested function it will return NULL.
* This is convenient for drivers that need to handle optional GPIOs.
*/
struct gpio_desc *__must_check gpiod_get_index_optional(struct device *dev,
const char *con_id,
unsigned int index)
{
struct gpio_desc *desc;
desc = gpiod_get_index(dev, con_id, index);
if (IS_ERR(desc)) {
if (PTR_ERR(desc) == -ENOENT)
return NULL;
}
return desc;
}
EXPORT_SYMBOL_GPL(gpiod_get_index_optional);
/**
* gpiod_put - dispose of a GPIO descriptor
* @desc: GPIO descriptor to dispose of

Просмотреть файл

@ -15,6 +15,8 @@
#include <linux/err.h>
#include <linux/device.h>
enum of_gpio_flags;
/**
* struct acpi_gpio_info - ACPI GPIO specific information
* @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo
@ -46,4 +48,7 @@ acpi_get_gpiod_by_index(struct device *dev, int index,
int gpiochip_request_own_desc(struct gpio_desc *desc, const char *label);
void gpiochip_free_own_desc(struct gpio_desc *desc);
struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
const char *list_name, int index, enum of_gpio_flags *flags);
#endif /* GPIOLIB_H */

Просмотреть файл

@ -1,6 +1,7 @@
#ifndef __LINUX_GPIO_CONSUMER_H
#define __LINUX_GPIO_CONSUMER_H
#include <linux/bug.h>
#include <linux/err.h>
#include <linux/kernel.h>
@ -23,6 +24,12 @@ struct gpio_desc *__must_check gpiod_get(struct device *dev,
struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
const char *con_id,
unsigned int idx);
struct gpio_desc *__must_check gpiod_get_optional(struct device *dev,
const char *con_id);
struct gpio_desc *__must_check gpiod_get_index_optional(struct device *dev,
const char *con_id,
unsigned int index);
void gpiod_put(struct gpio_desc *desc);
struct gpio_desc *__must_check devm_gpiod_get(struct device *dev,
@ -30,6 +37,12 @@ struct gpio_desc *__must_check devm_gpiod_get(struct device *dev,
struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
const char *con_id,
unsigned int idx);
struct gpio_desc *__must_check devm_gpiod_get_optional(struct device *dev,
const char *con_id);
struct gpio_desc *__must_check
devm_gpiod_get_index_optional(struct device *dev, const char *con_id,
unsigned int index);
void devm_gpiod_put(struct device *dev, struct gpio_desc *desc);
int gpiod_get_direction(const struct gpio_desc *desc);
@ -73,6 +86,20 @@ static inline struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
{
return ERR_PTR(-ENOSYS);
}
static inline struct gpio_desc *__must_check
gpiod_get_optional(struct device *dev, const char *con_id)
{
return ERR_PTR(-ENOSYS);
}
static inline struct gpio_desc *__must_check
gpiod_get_index_optional(struct device *dev, const char *con_id,
unsigned int index)
{
return ERR_PTR(-ENOSYS);
}
static inline void gpiod_put(struct gpio_desc *desc)
{
might_sleep();
@ -93,6 +120,20 @@ struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
{
return ERR_PTR(-ENOSYS);
}
static inline struct gpio_desc *__must_check
devm_gpiod_get_optional(struct device *dev, const char *con_id)
{
return ERR_PTR(-ENOSYS);
}
static inline struct gpio_desc *__must_check
devm_gpiod_get_index_optional(struct device *dev, const char *con_id,
unsigned int index)
{
return ERR_PTR(-ENOSYS);
}
static inline void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
{
might_sleep();

Просмотреть файл

@ -51,7 +51,10 @@ struct seq_file;
* format specifier for an unsigned int. It is substituted by the actual
* number of the gpio.
* @can_sleep: flag must be set iff get()/set() methods sleep, as they
* must while accessing GPIO expander chips over I2C or SPI
* must while accessing GPIO expander chips over I2C or SPI. This
* implies that if the chip supports IRQs, these IRQs need to be threaded
* as the chip access may sleep when e.g. reading out the IRQ status
* registers.
* @exported: flags if the gpiochip is exported for use from sysfs. Private.
*
* A gpio_chip can help platforms abstract various sources of GPIOs so

Просмотреть файл

@ -111,7 +111,6 @@ enum tx3589x_block {
#define TC3589x_INT_PORIRQ 7
#define TC3589x_NR_INTERNAL_IRQS 8
#define TC3589x_INT_GPIO(x) (TC3589x_NR_INTERNAL_IRQS + (x))
struct tc3589x {
struct mutex lock;

Просмотреть файл

@ -19,7 +19,6 @@
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/gpio/consumer.h>
struct device_node;
@ -48,7 +47,7 @@ static inline struct of_mm_gpio_chip *to_of_mm_gpio_chip(struct gpio_chip *gc)
return container_of(gc, struct of_mm_gpio_chip, gc);
}
extern struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
extern int of_get_named_gpio_flags(struct device_node *np,
const char *list_name, int index, enum of_gpio_flags *flags);
extern int of_mm_gpiochip_add(struct device_node *np,
@ -63,10 +62,10 @@ extern int of_gpio_simple_xlate(struct gpio_chip *gc,
#else /* CONFIG_OF_GPIO */
/* Drivers may not strictly depend on the GPIO support, so let them link. */
static inline struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
static inline int of_get_named_gpio_flags(struct device_node *np,
const char *list_name, int index, enum of_gpio_flags *flags)
{
return ERR_PTR(-ENOSYS);
return -ENOSYS;
}
static inline int of_gpio_simple_xlate(struct gpio_chip *gc,
@ -81,18 +80,6 @@ static inline void of_gpiochip_remove(struct gpio_chip *gc) { }
#endif /* CONFIG_OF_GPIO */
static inline int of_get_named_gpio_flags(struct device_node *np,
const char *list_name, int index, enum of_gpio_flags *flags)
{
struct gpio_desc *desc;
desc = of_get_named_gpiod_flags(np, list_name, index, flags);
if (IS_ERR(desc))
return PTR_ERR(desc);
else
return desc_to_gpio(desc);
}
/**
* of_gpio_named_count() - Count GPIOs for a device
* @np: device node to count GPIOs for
@ -129,22 +116,6 @@ static inline int of_gpio_count(struct device_node *np)
return of_gpio_named_count(np, "gpios");
}
/**
* of_get_gpiod_flags() - Get a GPIO descriptor and flags to use with GPIO API
* @np: device node to get GPIO from
* @index: index of the GPIO
* @flags: a flags pointer to fill in
*
* Returns GPIO descriptor to use with Linux generic GPIO API, or a errno
* value on the error condition. If @flags is not NULL the function also fills
* in flags for the GPIO.
*/
static inline struct gpio_desc *of_get_gpiod_flags(struct device_node *np,
int index, enum of_gpio_flags *flags)
{
return of_get_named_gpiod_flags(np, "gpios", index, flags);
}
static inline int of_get_gpio_flags(struct device_node *np, int index,
enum of_gpio_flags *flags)
{