Merge tag 'gpio-v4.5-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio

Pull GPIO updates from Linus Walleij:
 "Here is the bulk of GPIO changes for v4.5.

  Notably there are big refactorings mostly by myself, aimed at getting
  the gpio_chip into a shape that makes me believe I can proceed to
  preserve state for a proper userspace ABI (character device) that has
  already been proposed once, but resulted in the feedback that I need
  to go back and restructure stuff.  So I've been restructuring stuff.
  On the way I ran into brokenness (return code from the get_value()
  callback) and had to fix it.  Also, refactored generic GPIO to be
  simpler.

  Some of that is still waiting to trickle down from the subsystems all
  over the kernel that provide random gpio_chips, I've touched every
  single GPIO driver in the kernel now, oh man I didn't know I was
  responsible for so much...

  Apart from that we're churning along as usual.

  I took some effort to test and retest so it should merge nicely and we
  shook out a couple of bugs in -next.

  Infrastructural changes:

   - In struct gpio_chip, rename the .dev node to .parent to better
     reflect the fact that this is not the GPIO struct device
     abstraction.  We will add that soon so this would be totallt
     confusing.

   - It was noted that the driver .get_value() callbacks was sometimes
     reporting negative -ERR values to the gpiolib core, expecting them
     to be propagated to consumer gpiod_get_value() and gpio_get_value()
     calls.  This was not happening, so as there was a mess of drivers
     returning negative errors and some returning "anything else than
     zero" to indicate that a line was active.  As some would have bit
     31 set to indicate "line active" it clashed with negative error
     codes.  This is fixed by the largeish series clamping values in all
     drivers with !!value to [0,1] and then augmenting the code to
     propagate error codes to consumers.  (Includes some ACKed patches
     in other subsystems.)

   - Add a void *data pointer to struct gpio_chip.  The container_of()
     design pattern is indeed very nice, but we want to reform the
     struct gpio_chip to be a non-volative, stateless business, and keep
     states internal to the gpiolib to be able to hold on to the state
     when adding a proper userspace ABI (character device) further down
     the road.  To achieve this, drivers need a handle at the internal
     state that is not dependent on their struct gpio_chip() so we add
     gpiochip_add_data() and gpiochip_get_data() following the pattern
     of many other subsystems.  All the "use gpiochip data pointer"
     patches transforms drivers to this scheme.

   - The Generic GPIO chip header has been merged into the general
     <linux/gpio/driver.h> header, and the custom header for that
     removed.  Instead of having a separate mm_gpio_chip struct for
     these generic drivers, merge that into struct gpio_chip,
     simplifying the code and removing the need for separate and
     confusing includes.

  Misc improvements:

   - Stabilize the way GPIOs are looked up from the ACPI legacy
     specification.

   - Incremental driver features for PXA, PCA953X, Lantiq (patches from
     the OpenWRT community), RCAR, Zynq, PL061, 104-idi-48

  New drivers:

   - Add a GPIO chip to the ALSA SoC AC97 driver.

   - Add a new Broadcom NSP SoC driver (this lands in the pinctrl dir,
     but the branch is merged here too to account for infrastructural
     changes).

   - The sx150x driver now supports the sx1502"

* tag 'gpio-v4.5-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: (220 commits)
  gpio: generic: make bgpio_pdata always visible
  gpiolib: fix chip order in gpio list
  gpio: mpc8xxx: Do not use gpiochip_get_data() in mpc8xxx_gpio_save_regs()
  gpio: mm-lantiq: Do not use gpiochip_get_data() in ltq_mm_save_regs()
  gpio: brcmstb: Allow building driver for BMIPS_GENERIC
  gpio: brcmstb: Set endian flags for big-endian MIPS
  gpio: moxart: fix build regression
  gpio: xilinx: Do not use gpiochip_get_data() in xgpio_save_regs()
  leds: pca9532: use gpiochip data pointer
  leds: tca6507: use gpiochip data pointer
  hid: cp2112: use gpiochip data pointer
  bcma: gpio: use gpiochip data pointer
  avr32: gpio: use gpiochip data pointer
  video: fbdev: via: use gpiochip data pointer
  gpio: pch: Optimize pch_gpio_get()
  Revert "pinctrl: lantiq: Implement gpio_chip.to_irq"
  pinctrl: nsp-gpio: use gpiochip data pointer
  pinctrl: vt8500-wmt: use gpiochip data pointer
  pinctrl: exynos5440: use gpiochip data pointer
  pinctrl: at91-pio4: use gpiochip data pointer
  ...
This commit is contained in:
Linus Torvalds
2016-01-17 12:32:01 -08:00
186 changed files with 2693 additions and 2506 deletions

View File

@@ -25,6 +25,7 @@ Required properties:
ti,tca6416
ti,tca6424
ti,tca9539
onsemi,pca9654
exar,xra1202
Example:

View File

@@ -5,7 +5,8 @@ Required properties:
- compatible: should be "semtech,sx1506q",
"semtech,sx1508q",
"semtech,sx1509q".
"semtech,sx1509q",
"semtech,sx1502q".
- reg: The I2C slave address for this device.

View File

@@ -0,0 +1,16 @@
* TPS65086 GPO Controller bindings
Required properties:
- compatible : Should be "ti,tps65086-gpio".
- gpio-controller : Marks the device node as a GPIO Controller.
- #gpio-cells : Should be two. The first cell is the pin number
and the second cell is used to specify flags.
See ../gpio/gpio.txt for possible values.
Example:
gpio4: gpio {
compatible = "ti,tps65086-gpio";
gpio-controller;
#gpio-cells = <2>;
};

View File

@@ -240,6 +240,12 @@ L: lm-sensors@lm-sensors.org
S: Maintained
F: drivers/hwmon/abituguru3.c
ACCES 104-IDI-48 GPIO DRIVER
M: "William Breathitt Gray" <vilhelm.gray@gmail.com>
L: linux-gpio@vger.kernel.org
S: Maintained
F: drivers/gpio/gpio-104-idi-48.c
ACCES 104-IDIO-16 GPIO DRIVER
M: "William Breathitt Gray" <vilhelm.gray@gmail.com>
L: linux-gpio@vger.kernel.org
@@ -7821,11 +7827,12 @@ F: drivers/usb/*/*omap*
F: arch/arm/*omap*/usb*
OMAP GPIO DRIVER
M: Javier Martinez Canillas <javier@dowhile0.org>
M: Grygorii Strashko <grygorii.strashko@ti.com>
M: Santosh Shilimkar <ssantosh@kernel.org>
M: Kevin Hilman <khilman@deeprootsystems.com>
L: linux-omap@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/gpio/gpio-omap.txt
F: drivers/gpio/gpio-omap.c
OMAP/NEWFLOW NANOBONE MACHINE SUPPORT
@@ -8685,6 +8692,12 @@ F: include/sound/pxa2xx-lib.h
F: sound/arm/pxa*
F: sound/soc/pxa/
PXA GPIO DRIVER
M: Robert Jarzmik <robert.jarzmik@free.fr>
L: linux-gpio@vger.kernel.org
S: Maintained
F: drivers/gpio/gpio-pxa.c
PXA3xx NAND FLASH DRIVER
M: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
L: linux-mtd@lists.infradead.org

View File

@@ -31,7 +31,7 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand-gpio.h>
#include <linux/platform_device.h>
#include <linux/basic_mmio_gpio.h>
#include <linux/gpio/driver.h>
#include <mach/hardware.h>
#include <asm/sizes.h>

View File

@@ -28,7 +28,7 @@
#include <linux/leds.h>
#include <linux/sizes.h>
#include <linux/backlight.h>
#include <linux/basic_mmio_gpio.h>
#include <linux/gpio/driver.h>
#include <linux/platform_device.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand-gpio.h>

View File

@@ -17,7 +17,7 @@
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/physmap.h>
#include <linux/basic_mmio_gpio.h>
#include <linux/gpio/driver.h>
#include <linux/gpio.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>

View File

@@ -11,7 +11,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/basic_mmio_gpio.h>
#include <linux/gpio/driver.h>
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>

View File

@@ -29,7 +29,7 @@
#include <linux/pwm_backlight.h>
#include <linux/dm9000.h>
#include <linux/gpio_keys.h>
#include <linux/basic_mmio_gpio.h>
#include <linux/gpio/driver.h>
#include <linux/spi/spi.h>
#include <linux/platform_data/pca953x.h>

View File

@@ -203,7 +203,7 @@ fail:
static int direction_input(struct gpio_chip *chip, unsigned offset)
{
struct pio_device *pio = container_of(chip, struct pio_device, chip);
struct pio_device *pio = gpiochip_get_data(chip);
u32 mask = 1 << offset;
if (!(pio_readl(pio, PSR) & mask))
@@ -215,7 +215,7 @@ static int direction_input(struct gpio_chip *chip, unsigned offset)
static int gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct pio_device *pio = container_of(chip, struct pio_device, chip);
struct pio_device *pio = gpiochip_get_data(chip);
return (pio_readl(pio, PDSR) >> offset) & 1;
}
@@ -224,7 +224,7 @@ static void gpio_set(struct gpio_chip *chip, unsigned offset, int value);
static int direction_output(struct gpio_chip *chip, unsigned offset, int value)
{
struct pio_device *pio = container_of(chip, struct pio_device, chip);
struct pio_device *pio = gpiochip_get_data(chip);
u32 mask = 1 << offset;
if (!(pio_readl(pio, PSR) & mask))
@@ -237,7 +237,7 @@ static int direction_output(struct gpio_chip *chip, unsigned offset, int value)
static void gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct pio_device *pio = container_of(chip, struct pio_device, chip);
struct pio_device *pio = gpiochip_get_data(chip);
u32 mask = 1 << offset;
if (value)
@@ -335,7 +335,7 @@ gpio_irq_setup(struct pio_device *pio, int irq, int gpio_irq)
*/
static void pio_bank_show(struct seq_file *s, struct gpio_chip *chip)
{
struct pio_device *pio = container_of(chip, struct pio_device, chip);
struct pio_device *pio = gpiochip_get_data(chip);
u32 psr, osr, imr, pdsr, pusr, ifsr, mdsr;
unsigned i;
u32 mask;
@@ -397,7 +397,7 @@ static int __init pio_probe(struct platform_device *pdev)
pio->chip.label = pio->name;
pio->chip.base = pdev->id * 32;
pio->chip.ngpio = 32;
pio->chip.dev = &pdev->dev;
pio->chip.parent = &pdev->dev;
pio->chip.owner = THIS_MODULE;
pio->chip.direction_input = direction_input;
@@ -406,7 +406,7 @@ static int __init pio_probe(struct platform_device *pdev)
pio->chip.set = gpio_set;
pio->chip.dbg_show = pio_bank_show;
gpiochip_add(&pio->chip);
gpiochip_add_data(&pio->chip, pio);
gpio_irq_setup(pio, irq, gpio_irq_base);

View File

@@ -17,14 +17,9 @@
#define BCMA_GPIO_MAX_PINS 32
static inline struct bcma_drv_cc *bcma_gpio_get_cc(struct gpio_chip *chip)
{
return container_of(chip, struct bcma_drv_cc, gpio);
}
static int bcma_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
{
struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
struct bcma_drv_cc *cc = gpiochip_get_data(chip);
return !!bcma_chipco_gpio_in(cc, 1 << gpio);
}
@@ -32,14 +27,14 @@ static int bcma_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
static void bcma_gpio_set_value(struct gpio_chip *chip, unsigned gpio,
int value)
{
struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
struct bcma_drv_cc *cc = gpiochip_get_data(chip);
bcma_chipco_gpio_out(cc, 1 << gpio, value ? 1 << gpio : 0);
}
static int bcma_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
{
struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
struct bcma_drv_cc *cc = gpiochip_get_data(chip);
bcma_chipco_gpio_outen(cc, 1 << gpio, 0);
return 0;
@@ -48,7 +43,7 @@ static int bcma_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
static int bcma_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
int value)
{
struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
struct bcma_drv_cc *cc = gpiochip_get_data(chip);
bcma_chipco_gpio_outen(cc, 1 << gpio, 1 << gpio);
bcma_chipco_gpio_out(cc, 1 << gpio, value ? 1 << gpio : 0);
@@ -57,7 +52,7 @@ static int bcma_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
static int bcma_gpio_request(struct gpio_chip *chip, unsigned gpio)
{
struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
struct bcma_drv_cc *cc = gpiochip_get_data(chip);
bcma_chipco_gpio_control(cc, 1 << gpio, 0);
/* clear pulldown */
@@ -70,7 +65,7 @@ static int bcma_gpio_request(struct gpio_chip *chip, unsigned gpio)
static void bcma_gpio_free(struct gpio_chip *chip, unsigned gpio)
{
struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
struct bcma_drv_cc *cc = gpiochip_get_data(chip);
/* clear pullup */
bcma_chipco_gpio_pullup(cc, 1 << gpio, 0);
@@ -81,7 +76,7 @@ static void bcma_gpio_free(struct gpio_chip *chip, unsigned gpio)
static void bcma_gpio_irq_unmask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct bcma_drv_cc *cc = bcma_gpio_get_cc(gc);
struct bcma_drv_cc *cc = gpiochip_get_data(gc);
int gpio = irqd_to_hwirq(d);
u32 val = bcma_chipco_gpio_in(cc, BIT(gpio));
@@ -92,7 +87,7 @@ static void bcma_gpio_irq_unmask(struct irq_data *d)
static void bcma_gpio_irq_mask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct bcma_drv_cc *cc = bcma_gpio_get_cc(gc);
struct bcma_drv_cc *cc = gpiochip_get_data(gc);
int gpio = irqd_to_hwirq(d);
bcma_chipco_gpio_intmask(cc, BIT(gpio), 0);
@@ -188,7 +183,7 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
chip->direction_input = bcma_gpio_direction_input;
chip->direction_output = bcma_gpio_direction_output;
chip->owner = THIS_MODULE;
chip->dev = bcma_bus_get_host_dev(bus);
chip->parent = bcma_bus_get_host_dev(bus);
#if IS_BUILTIN(CONFIG_OF)
if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
chip->of_node = cc->core->dev.of_node;
@@ -216,7 +211,7 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
else
chip->base = -1;
err = gpiochip_add(chip);
err = gpiochip_add_data(chip, cc);
if (err)
return err;

View File

@@ -134,8 +134,8 @@ config GPIO_BCM_KONA
config GPIO_BRCMSTB
tristate "BRCMSTB GPIO support"
default y if ARCH_BRCMSTB
depends on OF_GPIO && (ARCH_BRCMSTB || COMPILE_TEST)
default y if (ARCH_BRCMSTB || BMIPS_GENERIC)
depends on OF_GPIO && (ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST)
select GPIO_GENERIC
select GPIOLIB_IRQCHIP
help
@@ -496,8 +496,21 @@ menu "Port-mapped I/O GPIO drivers"
config GPIO_104_IDIO_16
tristate "ACCES 104-IDIO-16 GPIO support"
select GPIOLIB_IRQCHIP
help
Enables GPIO support for the ACCES 104-IDIO-16 family.
Enables GPIO support for the ACCES 104-IDIO-16 family. The base port
address for the device may be set via the idio_16_base module
parameter. The interrupt line number for the device may be set via the
idio_16_irq module parameter.
config GPIO_104_IDI_48
tristate "ACCES 104-IDI-48 GPIO support"
select GPIOLIB_IRQCHIP
help
Enables GPIO support for the ACCES 104-IDI-48 family. The base port
address for the device may be configured via the idi_48_base module
parameter. The interrupt line number for the device may be configured
via the idi_48_irq module parameter.
config GPIO_F7188X
tristate "F71869, F71869A, F71882FG and F71889F GPIO support"
@@ -907,7 +920,6 @@ menu "PCI GPIO expanders"
config GPIO_AMD8111
tristate "AMD 8111 GPIO driver"
depends on PCI
help
The AMD 8111 south bridge contains 32 GPIO pins which can be used.
@@ -919,7 +931,7 @@ config GPIO_AMD8111
config GPIO_BT8XX
tristate "BT8XX GPIO abuser"
depends on PCI && VIDEO_BT848=n
depends on VIDEO_BT848=n
help
The BT8xx frame grabber chip has 24 GPIO pins that can be abused
as a cheap PCI GPIO card.
@@ -935,14 +947,13 @@ config GPIO_BT8XX
config GPIO_INTEL_MID
bool "Intel Mid GPIO support"
depends on PCI && X86
depends on X86
select GPIOLIB_IRQCHIP
help
Say Y here to support Intel Mid GPIO.
config GPIO_ML_IOH
tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support"
depends on PCI
select GENERIC_IRQ_CHIP
help
ML7213 is companion chip for Intel Atom E6xx series.
@@ -952,7 +963,7 @@ config GPIO_ML_IOH
config GPIO_PCH
tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7223/ML7831) GPIO"
depends on PCI && (X86_32 || COMPILE_TEST)
depends on X86_32 || MIPS || COMPILE_TEST
select GENERIC_IRQ_CHIP
help
This driver is for PCH(Platform controller Hub) GPIO of Intel Topcliff
@@ -968,7 +979,6 @@ config GPIO_PCH
config GPIO_RDC321X
tristate "RDC R-321x GPIO support"
depends on PCI
select MFD_CORE
select MFD_RDC321X
help
@@ -977,7 +987,7 @@ config GPIO_RDC321X
config GPIO_SODAVILLE
bool "Intel Sodaville GPIO support"
depends on X86 && PCI && OF
depends on X86 && OF
select GPIO_GENERIC
select GENERIC_IRQ_CHIP
help
@@ -1028,7 +1038,7 @@ menu "USB GPIO expanders"
config GPIO_VIPERBOARD
tristate "Viperboard GPIO a & b support"
depends on MFD_VIPERBOARD && USB
depends on MFD_VIPERBOARD
help
Say yes here to access the GPIO signals of Nano River
Technologies Viperboard. There are two GPIO chips on the

View File

@@ -13,6 +13,7 @@ obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o
obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
obj-$(CONFIG_GPIO_104_IDIO_16) += gpio-104-idio-16.o
obj-$(CONFIG_GPIO_104_IDI_48) += gpio-104-idi-48.o
obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o
obj-$(CONFIG_GPIO_74XX_MMIO) += gpio-74xx-mmio.o
obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o

View File

@@ -0,0 +1,343 @@
/*
* GPIO driver for the ACCES 104-IDI-48 family
* Copyright (C) 2015 William Breathitt Gray
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/gpio/driver.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/irqdesc.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
static unsigned idi_48_base;
module_param(idi_48_base, uint, 0);
MODULE_PARM_DESC(idi_48_base, "ACCES 104-IDI-48 base address");
static unsigned idi_48_irq;
module_param(idi_48_irq, uint, 0);
MODULE_PARM_DESC(idi_48_irq, "ACCES 104-IDI-48 interrupt line number");
/**
* struct idi_48_gpio - GPIO device private data structure
* @chip: instance of the gpio_chip
* @lock: synchronization lock to prevent I/O race conditions
* @ack_lock: synchronization lock to prevent IRQ handler race conditions
* @irq_mask: input bits affected by interrupts
* @base: base port address of the GPIO device
* @extent: extent of port address region of the GPIO device
* @irq: Interrupt line number
* @cos_enb: Change-Of-State IRQ enable boundaries mask
*/
struct idi_48_gpio {
struct gpio_chip chip;
spinlock_t lock;
spinlock_t ack_lock;
unsigned char irq_mask[6];
unsigned base;
unsigned extent;
unsigned irq;
unsigned char cos_enb;
};
static int idi_48_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
{
return 1;
}
static int idi_48_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
return 0;
}
static int idi_48_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct idi_48_gpio *const idi48gpio = gpiochip_get_data(chip);
unsigned i;
const unsigned register_offset[6] = { 0, 1, 2, 4, 5, 6 };
unsigned base_offset;
unsigned mask;
for (i = 0; i < 48; i += 8)
if (offset < i + 8) {
base_offset = register_offset[i / 8];
mask = BIT(offset - i);
return !!(inb(idi48gpio->base + base_offset) & mask);
}
/* The following line should never execute since offset < 48 */
return 0;
}
static void idi_48_irq_ack(struct irq_data *data)
{
}
static void idi_48_irq_mask(struct irq_data *data)
{
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct idi_48_gpio *const idi48gpio = gpiochip_get_data(chip);
const unsigned offset = irqd_to_hwirq(data);
unsigned i;
unsigned mask;
unsigned boundary;
unsigned long flags;
for (i = 0; i < 48; i += 8)
if (offset < i + 8) {
mask = BIT(offset - i);
boundary = i / 8;
idi48gpio->irq_mask[boundary] &= ~mask;
if (!idi48gpio->irq_mask[boundary]) {
idi48gpio->cos_enb &= ~BIT(boundary);
spin_lock_irqsave(&idi48gpio->lock, flags);
outb(idi48gpio->cos_enb, idi48gpio->base + 7);
spin_unlock_irqrestore(&idi48gpio->lock, flags);
}
return;
}
}
static void idi_48_irq_unmask(struct irq_data *data)
{
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct idi_48_gpio *const idi48gpio = gpiochip_get_data(chip);
const unsigned offset = irqd_to_hwirq(data);
unsigned i;
unsigned mask;
unsigned boundary;
unsigned prev_irq_mask;
unsigned long flags;
for (i = 0; i < 48; i += 8)
if (offset < i + 8) {
mask = BIT(offset - i);
boundary = i / 8;
prev_irq_mask = idi48gpio->irq_mask[boundary];
idi48gpio->irq_mask[boundary] |= mask;
if (!prev_irq_mask) {
idi48gpio->cos_enb |= BIT(boundary);
spin_lock_irqsave(&idi48gpio->lock, flags);
outb(idi48gpio->cos_enb, idi48gpio->base + 7);
spin_unlock_irqrestore(&idi48gpio->lock, flags);
}
return;
}
}
static int idi_48_irq_set_type(struct irq_data *data, unsigned flow_type)
{
/* The only valid irq types are none and both-edges */
if (flow_type != IRQ_TYPE_NONE &&
(flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
return -EINVAL;
return 0;
}
static struct irq_chip idi_48_irqchip = {
.name = "104-idi-48",
.irq_ack = idi_48_irq_ack,
.irq_mask = idi_48_irq_mask,
.irq_unmask = idi_48_irq_unmask,
.irq_set_type = idi_48_irq_set_type
};
static irqreturn_t idi_48_irq_handler(int irq, void *dev_id)
{
struct idi_48_gpio *const idi48gpio = dev_id;
unsigned long cos_status;
unsigned long boundary;
unsigned long irq_mask;
unsigned long bit_num;
unsigned long gpio;
struct gpio_chip *const chip = &idi48gpio->chip;
spin_lock(&idi48gpio->ack_lock);
spin_lock(&idi48gpio->lock);
cos_status = inb(idi48gpio->base + 7);
spin_unlock(&idi48gpio->lock);
/* IRQ Status (bit 6) is active low (0 = IRQ generated by device) */
if (cos_status & BIT(6)) {
spin_unlock(&idi48gpio->ack_lock);
return IRQ_NONE;
}
/* Bit 0-5 indicate which Change-Of-State boundary triggered the IRQ */
cos_status &= 0x3F;
for_each_set_bit(boundary, &cos_status, 6) {
irq_mask = idi48gpio->irq_mask[boundary];
for_each_set_bit(bit_num, &irq_mask, 8) {
gpio = bit_num + boundary * 8;
generic_handle_irq(irq_find_mapping(chip->irqdomain,
gpio));
}
}
spin_unlock(&idi48gpio->ack_lock);
return IRQ_HANDLED;
}
static int __init idi_48_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct idi_48_gpio *idi48gpio;
const unsigned base = idi_48_base;
const unsigned extent = 8;
const char *const name = dev_name(dev);
int err;
const unsigned irq = idi_48_irq;
idi48gpio = devm_kzalloc(dev, sizeof(*idi48gpio), GFP_KERNEL);
if (!idi48gpio)
return -ENOMEM;
if (!request_region(base, extent, name)) {
dev_err(dev, "Unable to lock %s port addresses (0x%X-0x%X)\n",
name, base, base + extent);
err = -EBUSY;
goto err_lock_io_port;
}
idi48gpio->chip.label = name;
idi48gpio->chip.parent = dev;
idi48gpio->chip.owner = THIS_MODULE;
idi48gpio->chip.base = -1;
idi48gpio->chip.ngpio = 48;
idi48gpio->chip.get_direction = idi_48_gpio_get_direction;
idi48gpio->chip.direction_input = idi_48_gpio_direction_input;
idi48gpio->chip.get = idi_48_gpio_get;
idi48gpio->base = base;
idi48gpio->extent = extent;
idi48gpio->irq = irq;
spin_lock_init(&idi48gpio->lock);
dev_set_drvdata(dev, idi48gpio);
err = gpiochip_add_data(&idi48gpio->chip, idi48gpio);
if (err) {
dev_err(dev, "GPIO registering failed (%d)\n", err);
goto err_gpio_register;
}
/* Disable IRQ by default */
outb(0, base + 7);
inb(base + 7);
err = gpiochip_irqchip_add(&idi48gpio->chip, &idi_48_irqchip, 0,
handle_edge_irq, IRQ_TYPE_NONE);
if (err) {
dev_err(dev, "Could not add irqchip (%d)\n", err);
goto err_gpiochip_irqchip_add;
}
err = request_irq(irq, idi_48_irq_handler, 0, name, idi48gpio);
if (err) {
dev_err(dev, "IRQ handler registering failed (%d)\n", err);
goto err_request_irq;
}
return 0;
err_request_irq:
err_gpiochip_irqchip_add:
gpiochip_remove(&idi48gpio->chip);
err_gpio_register:
release_region(base, extent);
err_lock_io_port:
return err;
}
static int idi_48_remove(struct platform_device *pdev)
{
struct idi_48_gpio *const idi48gpio = platform_get_drvdata(pdev);
free_irq(idi48gpio->irq, idi48gpio);
gpiochip_remove(&idi48gpio->chip);
release_region(idi48gpio->base, idi48gpio->extent);
return 0;
}
static struct platform_device *idi_48_device;
static struct platform_driver idi_48_driver = {
.driver = {
.name = "104-idi-48"
},
.remove = idi_48_remove
};
static void __exit idi_48_exit(void)
{
platform_device_unregister(idi_48_device);
platform_driver_unregister(&idi_48_driver);
}
static int __init idi_48_init(void)
{
int err;
idi_48_device = platform_device_alloc(idi_48_driver.driver.name, -1);
if (!idi_48_device)
return -ENOMEM;
err = platform_device_add(idi_48_device);
if (err)
goto err_platform_device;
err = platform_driver_probe(&idi_48_driver, idi_48_probe);
if (err)
goto err_platform_driver;
return 0;
err_platform_driver:
platform_device_del(idi_48_device);
err_platform_device:
platform_device_put(idi_48_device);
return err;
}
module_init(idi_48_init);
module_exit(idi_48_exit);
MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
MODULE_DESCRIPTION("ACCES 104-IDI-48 GPIO driver");
MODULE_LICENSE("GPL");

View File

@@ -11,11 +11,14 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/gpio/driver.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/irqdesc.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -25,20 +28,27 @@
static unsigned idio_16_base;
module_param(idio_16_base, uint, 0);
MODULE_PARM_DESC(idio_16_base, "ACCES 104-IDIO-16 base address");
static unsigned idio_16_irq;
module_param(idio_16_irq, uint, 0);
MODULE_PARM_DESC(idio_16_irq, "ACCES 104-IDIO-16 interrupt line number");
/**
* struct idio_16_gpio - GPIO device private data structure
* @chip: instance of the gpio_chip
* @lock: synchronization lock to prevent gpio_set race conditions
* @lock: synchronization lock to prevent I/O race conditions
* @irq_mask: I/O bits affected by interrupts
* @base: base port address of the GPIO device
* @extent: extent of port address region of the GPIO device
* @irq: Interrupt line number
* @out_state: output bits state
*/
struct idio_16_gpio {
struct gpio_chip chip;
spinlock_t lock;
unsigned long irq_mask;
unsigned base;
unsigned extent;
unsigned irq;
unsigned out_state;
};
@@ -62,29 +72,24 @@ static int idio_16_gpio_direction_output(struct gpio_chip *chip,
return 0;
}
static struct idio_16_gpio *to_idio16gpio(struct gpio_chip *gc)
{
return container_of(gc, struct idio_16_gpio, chip);
}
static int idio_16_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct idio_16_gpio *const idio16gpio = to_idio16gpio(chip);
const unsigned BIT_MASK = 1U << (offset-16);
struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
const unsigned mask = BIT(offset-16);
if (offset < 16)
return -EINVAL;
if (offset < 24)
return !!(inb(idio16gpio->base + 1) & BIT_MASK);
return !!(inb(idio16gpio->base + 1) & mask);
return !!(inb(idio16gpio->base + 5) & (BIT_MASK>>8));
return !!(inb(idio16gpio->base + 5) & (mask>>8));
}
static void idio_16_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct idio_16_gpio *const idio16gpio = to_idio16gpio(chip);
const unsigned BIT_MASK = 1U << offset;
struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
const unsigned mask = BIT(offset);
unsigned long flags;
if (offset > 15)
@@ -93,9 +98,9 @@ static void idio_16_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
spin_lock_irqsave(&idio16gpio->lock, flags);
if (value)
idio16gpio->out_state |= BIT_MASK;
idio16gpio->out_state |= mask;
else
idio16gpio->out_state &= ~BIT_MASK;
idio16gpio->out_state &= ~mask;
if (offset > 7)
outb(idio16gpio->out_state >> 8, idio16gpio->base + 4);
@@ -105,29 +110,106 @@ static void idio_16_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
spin_unlock_irqrestore(&idio16gpio->lock, flags);
}
static void idio_16_irq_ack(struct irq_data *data)
{
}
static void idio_16_irq_mask(struct irq_data *data)
{
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
const unsigned long mask = BIT(irqd_to_hwirq(data));
unsigned long flags;
idio16gpio->irq_mask &= ~mask;
if (!idio16gpio->irq_mask) {
spin_lock_irqsave(&idio16gpio->lock, flags);
outb(0, idio16gpio->base + 2);
spin_unlock_irqrestore(&idio16gpio->lock, flags);
}
}
static void idio_16_irq_unmask(struct irq_data *data)
{
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
const unsigned long mask = BIT(irqd_to_hwirq(data));
const unsigned long prev_irq_mask = idio16gpio->irq_mask;
unsigned long flags;
idio16gpio->irq_mask |= mask;
if (!prev_irq_mask) {
spin_lock_irqsave(&idio16gpio->lock, flags);
inb(idio16gpio->base + 2);
spin_unlock_irqrestore(&idio16gpio->lock, flags);
}
}
static int idio_16_irq_set_type(struct irq_data *data, unsigned flow_type)
{
/* The only valid irq types are none and both-edges */
if (flow_type != IRQ_TYPE_NONE &&
(flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
return -EINVAL;
return 0;
}
static struct irq_chip idio_16_irqchip = {
.name = "104-idio-16",
.irq_ack = idio_16_irq_ack,
.irq_mask = idio_16_irq_mask,
.irq_unmask = idio_16_irq_unmask,
.irq_set_type = idio_16_irq_set_type
};
static irqreturn_t idio_16_irq_handler(int irq, void *dev_id)
{
struct idio_16_gpio *const idio16gpio = dev_id;
struct gpio_chip *const chip = &idio16gpio->chip;
int gpio;
for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio)
generic_handle_irq(irq_find_mapping(chip->irqdomain, gpio));
spin_lock(&idio16gpio->lock);
outb(0, idio16gpio->base + 1);
spin_unlock(&idio16gpio->lock);
return IRQ_HANDLED;
}
static int __init idio_16_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct idio_16_gpio *idio16gpio;
const unsigned base = idio_16_base;
const unsigned extent = 8;
const char *const name = dev_name(dev);
int err;
const unsigned BASE = idio_16_base;
const unsigned EXTENT = 8;
const char *const NAME = dev_name(dev);
const unsigned irq = idio_16_irq;
idio16gpio = devm_kzalloc(dev, sizeof(*idio16gpio), GFP_KERNEL);
if (!idio16gpio)
return -ENOMEM;
if (!request_region(BASE, EXTENT, NAME)) {
if (!request_region(base, extent, name)) {
dev_err(dev, "Unable to lock %s port addresses (0x%X-0x%X)\n",
NAME, BASE, BASE + EXTENT);
name, base, base + extent);
err = -EBUSY;
goto err_lock_io_port;
}
idio16gpio->chip.label = NAME;
idio16gpio->chip.dev = dev;
idio16gpio->chip.label = name;
idio16gpio->chip.parent = dev;
idio16gpio->chip.owner = THIS_MODULE;
idio16gpio->chip.base = -1;
idio16gpio->chip.ngpio = 32;
@@ -136,24 +218,45 @@ static int __init idio_16_probe(struct platform_device *pdev)
idio16gpio->chip.direction_output = idio_16_gpio_direction_output;
idio16gpio->chip.get = idio_16_gpio_get;
idio16gpio->chip.set = idio_16_gpio_set;
idio16gpio->base = BASE;
idio16gpio->extent = EXTENT;
idio16gpio->base = base;
idio16gpio->extent = extent;
idio16gpio->irq = irq;
idio16gpio->out_state = 0xFFFF;
spin_lock_init(&idio16gpio->lock);
dev_set_drvdata(dev, idio16gpio);
err = gpiochip_add(&idio16gpio->chip);
err = gpiochip_add_data(&idio16gpio->chip, idio16gpio);
if (err) {
dev_err(dev, "GPIO registering failed (%d)\n", err);
goto err_gpio_register;
}
/* Disable IRQ by default */
outb(0, base + 2);
outb(0, base + 1);
err = gpiochip_irqchip_add(&idio16gpio->chip, &idio_16_irqchip, 0,
handle_edge_irq, IRQ_TYPE_NONE);
if (err) {
dev_err(dev, "Could not add irqchip (%d)\n", err);
goto err_gpiochip_irqchip_add;
}
err = request_irq(irq, idio_16_irq_handler, 0, name, idio16gpio);
if (err) {
dev_err(dev, "IRQ handler registering failed (%d)\n", err);
goto err_request_irq;
}
return 0;
err_request_irq:
err_gpiochip_irqchip_add:
gpiochip_remove(&idio16gpio->chip);
err_gpio_register:
release_region(BASE, EXTENT);
release_region(base, extent);
err_lock_io_port:
return err;
}
@@ -162,6 +265,7 @@ static int idio_16_remove(struct platform_device *pdev)
{
struct idio_16_gpio *const idio16gpio = platform_get_drvdata(pdev);
free_irq(idio16gpio->irq, idio16gpio);
gpiochip_remove(&idio16gpio->chip);
release_region(idio16gpio->base, idio16gpio->extent);

View File

@@ -20,56 +20,34 @@
#define GEN_74X164_NUMBER_GPIOS 8
struct gen_74x164_chip {
u8 *buffer;
struct gpio_chip gpio_chip;
struct mutex lock;
u32 registers;
};
static struct gen_74x164_chip *gpio_to_74x164_chip(struct gpio_chip *gc)
{
return container_of(gc, struct gen_74x164_chip, gpio_chip);
}
static int __gen_74x164_write_config(struct gen_74x164_chip *chip)
{
struct spi_device *spi = to_spi_device(chip->gpio_chip.dev);
struct spi_message message;
struct spi_transfer *msg_buf;
int i, ret = 0;
msg_buf = kzalloc(chip->registers * sizeof(struct spi_transfer),
GFP_KERNEL);
if (!msg_buf)
return -ENOMEM;
spi_message_init(&message);
/*
* Since the registers are chained, every byte sent will make
* the previous byte shift to the next register in the
* chain. Thus, the first byte send will end up in the last
* chain. Thus, the first byte sent will end up in the last
* register at the end of the transfer. So, to have a logical
* numbering, send the bytes in reverse order so that the last
* byte of the buffer will end up in the last register.
* numbering, store the bytes in reverse order.
*/
for (i = chip->registers - 1; i >= 0; i--) {
msg_buf[i].tx_buf = chip->buffer + i;
msg_buf[i].len = sizeof(u8);
spi_message_add_tail(msg_buf + i, &message);
}
u8 buffer[0];
};
ret = spi_sync(spi, &message);
static int __gen_74x164_write_config(struct gen_74x164_chip *chip)
{
struct spi_transfer xfer = {
.tx_buf = chip->buffer,
.len = chip->registers,
};
kfree(msg_buf);
return ret;
return spi_sync_transfer(to_spi_device(chip->gpio_chip.parent),
&xfer, 1);
}
static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset)
{
struct gen_74x164_chip *chip = gpio_to_74x164_chip(gc);
u8 bank = offset / 8;
struct gen_74x164_chip *chip = gpiochip_get_data(gc);
u8 bank = chip->registers - 1 - offset / 8;
u8 pin = offset % 8;
int ret;
@@ -83,8 +61,8 @@ static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset)
static void gen_74x164_set_value(struct gpio_chip *gc,
unsigned offset, int val)
{
struct gen_74x164_chip *chip = gpio_to_74x164_chip(gc);
u8 bank = offset / 8;
struct gen_74x164_chip *chip = gpiochip_get_data(gc);
u8 bank = chip->registers - 1 - offset / 8;
u8 pin = offset % 8;
mutex_lock(&chip->lock);
@@ -107,6 +85,7 @@ static int gen_74x164_direction_output(struct gpio_chip *gc,
static int gen_74x164_probe(struct spi_device *spi)
{
struct gen_74x164_chip *chip;
u32 nregs;
int ret;
/*
@@ -118,7 +97,14 @@ static int gen_74x164_probe(struct spi_device *spi)
if (ret < 0)
return ret;
chip = devm_kzalloc(&spi->dev, sizeof(*chip), GFP_KERNEL);
if (of_property_read_u32(spi->dev.of_node, "registers-number",
&nregs)) {
dev_err(&spi->dev,
"Missing registers-number property in the DT.\n");
return -EINVAL;
}
chip = devm_kzalloc(&spi->dev, sizeof(*chip) + nregs, GFP_KERNEL);
if (!chip)
return -ENOMEM;
@@ -130,20 +116,11 @@ static int gen_74x164_probe(struct spi_device *spi)
chip->gpio_chip.set = gen_74x164_set_value;
chip->gpio_chip.base = -1;
if (of_property_read_u32(spi->dev.of_node, "registers-number",
&chip->registers)) {
dev_err(&spi->dev,
"Missing registers-number property in the DT.\n");
return -EINVAL;
}
chip->registers = nregs;
chip->gpio_chip.ngpio = GEN_74X164_NUMBER_GPIOS * chip->registers;
chip->buffer = devm_kzalloc(&spi->dev, chip->registers, GFP_KERNEL);
if (!chip->buffer)
return -ENOMEM;
chip->gpio_chip.can_sleep = true;
chip->gpio_chip.dev = &spi->dev;
chip->gpio_chip.parent = &spi->dev;
chip->gpio_chip.owner = THIS_MODULE;
mutex_init(&chip->lock);
@@ -154,7 +131,7 @@ static int gen_74x164_probe(struct spi_device *spi)
goto exit_destroy;
}
ret = gpiochip_add(&chip->gpio_chip);
ret = gpiochip_add_data(&chip->gpio_chip, chip);
if (!ret)
return 0;

View File

@@ -10,10 +10,9 @@
*/
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/basic_mmio_gpio.h>
#include <linux/gpio/driver.h>
#include <linux/platform_device.h>
#define MMIO_74XX_DIR_IN (0 << 8)
@@ -21,7 +20,7 @@
#define MMIO_74XX_BIT_CNT(x) ((x) & 0xff)
struct mmio_74xx_gpio_priv {
struct bgpio_chip bgc;
struct gpio_chip gc;
unsigned flags;
};
@@ -78,30 +77,23 @@ static const struct of_device_id mmio_74xx_gpio_ids[] = {
};
MODULE_DEVICE_TABLE(of, mmio_74xx_gpio_ids);
static inline struct mmio_74xx_gpio_priv *to_74xx_gpio(struct gpio_chip *gc)
{
struct bgpio_chip *bgc = to_bgpio_chip(gc);
return container_of(bgc, struct mmio_74xx_gpio_priv, bgc);
}
static int mmio_74xx_get_direction(struct gpio_chip *gc, unsigned offset)
{
struct mmio_74xx_gpio_priv *priv = to_74xx_gpio(gc);
struct mmio_74xx_gpio_priv *priv = gpiochip_get_data(gc);
return (priv->flags & MMIO_74XX_DIR_OUT) ? GPIOF_DIR_OUT : GPIOF_DIR_IN;
return !(priv->flags & MMIO_74XX_DIR_OUT);
}
static int mmio_74xx_dir_in(struct gpio_chip *gc, unsigned int gpio)
{
struct mmio_74xx_gpio_priv *priv = to_74xx_gpio(gc);
struct mmio_74xx_gpio_priv *priv = gpiochip_get_data(gc);
return (priv->flags & MMIO_74XX_DIR_OUT) ? -ENOTSUPP : 0;
}
static int mmio_74xx_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
{
struct mmio_74xx_gpio_priv *priv = to_74xx_gpio(gc);
struct mmio_74xx_gpio_priv *priv = gpiochip_get_data(gc);
if (priv->flags & MMIO_74XX_DIR_OUT) {
gc->set(gc, gpio, val);
@@ -134,28 +126,29 @@ static int mmio_74xx_gpio_probe(struct platform_device *pdev)
priv->flags = (uintptr_t) of_id->data;
err = bgpio_init(&priv->bgc, &pdev->dev,
err = bgpio_init(&priv->gc, &pdev->dev,
DIV_ROUND_UP(MMIO_74XX_BIT_CNT(priv->flags), 8),
dat, NULL, NULL, NULL, NULL, 0);
if (err)
return err;
priv->bgc.gc.direction_input = mmio_74xx_dir_in;
priv->bgc.gc.direction_output = mmio_74xx_dir_out;
priv->bgc.gc.get_direction = mmio_74xx_get_direction;
priv->bgc.gc.ngpio = MMIO_74XX_BIT_CNT(priv->flags);
priv->bgc.gc.owner = THIS_MODULE;
priv->gc.direction_input = mmio_74xx_dir_in;
priv->gc.direction_output = mmio_74xx_dir_out;
priv->gc.get_direction = mmio_74xx_get_direction;
priv->gc.ngpio = MMIO_74XX_BIT_CNT(priv->flags);
priv->gc.owner = THIS_MODULE;
platform_set_drvdata(pdev, priv);
return gpiochip_add(&priv->bgc.gc);
return gpiochip_add_data(&priv->gc, priv);
}
static int mmio_74xx_gpio_remove(struct platform_device *pdev)
{
struct mmio_74xx_gpio_priv *priv = platform_get_drvdata(pdev);
return bgpio_remove(&priv->bgc);
gpiochip_remove(&priv->gc);
return 0;
}
static struct platform_driver mmio_74xx_gpio_driver = {

View File

@@ -36,18 +36,13 @@ struct adnp {
u8 *irq_low;
};
static inline struct adnp *to_adnp(struct gpio_chip *chip)
{
return container_of(chip, struct adnp, gpio);
}
static int adnp_read(struct adnp *adnp, unsigned offset, uint8_t *value)
{
int err;
err = i2c_smbus_read_byte_data(adnp->client, offset);
if (err < 0) {
dev_err(adnp->gpio.dev, "%s failed: %d\n",
dev_err(adnp->gpio.parent, "%s failed: %d\n",
"i2c_smbus_read_byte_data()", err);
return err;
}
@@ -62,7 +57,7 @@ static int adnp_write(struct adnp *adnp, unsigned offset, uint8_t value)
err = i2c_smbus_write_byte_data(adnp->client, offset, value);
if (err < 0) {
dev_err(adnp->gpio.dev, "%s failed: %d\n",
dev_err(adnp->gpio.parent, "%s failed: %d\n",
"i2c_smbus_write_byte_data()", err);
return err;
}
@@ -72,7 +67,7 @@ static int adnp_write(struct adnp *adnp, unsigned offset, uint8_t value)
static int adnp_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct adnp *adnp = to_adnp(chip);
struct adnp *adnp = gpiochip_get_data(chip);
unsigned int reg = offset >> adnp->reg_shift;
unsigned int pos = offset & 7;
u8 value;
@@ -106,7 +101,7 @@ static void __adnp_gpio_set(struct adnp *adnp, unsigned offset, int value)
static void adnp_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct adnp *adnp = to_adnp(chip);
struct adnp *adnp = gpiochip_get_data(chip);
mutex_lock(&adnp->i2c_lock);
__adnp_gpio_set(adnp, offset, value);
@@ -115,7 +110,7 @@ static void adnp_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
static int adnp_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
struct adnp *adnp = to_adnp(chip);
struct adnp *adnp = gpiochip_get_data(chip);
unsigned int reg = offset >> adnp->reg_shift;
unsigned int pos = offset & 7;
u8 value;
@@ -150,7 +145,7 @@ out:
static int adnp_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
int value)
{
struct adnp *adnp = to_adnp(chip);
struct adnp *adnp = gpiochip_get_data(chip);
unsigned int reg = offset >> adnp->reg_shift;
unsigned int pos = offset & 7;
int err;
@@ -187,7 +182,7 @@ out:
static void adnp_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
{
struct adnp *adnp = to_adnp(chip);
struct adnp *adnp = gpiochip_get_data(chip);
unsigned int num_regs = 1 << adnp->reg_shift, i, j;
int err;
@@ -266,11 +261,11 @@ static int adnp_gpio_setup(struct adnp *adnp, unsigned int num_gpios)
chip->base = -1;
chip->ngpio = num_gpios;
chip->label = adnp->client->name;
chip->dev = &adnp->client->dev;
chip->of_node = chip->dev->of_node;
chip->parent = &adnp->client->dev;
chip->of_node = chip->parent->of_node;
chip->owner = THIS_MODULE;
err = gpiochip_add(chip);
err = gpiochip_add_data(chip, adnp);
if (err)
return err;
@@ -340,7 +335,7 @@ static irqreturn_t adnp_irq(int irq, void *data)
static void adnp_irq_mask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct adnp *adnp = to_adnp(gc);
struct adnp *adnp = gpiochip_get_data(gc);
unsigned int reg = d->hwirq >> adnp->reg_shift;
unsigned int pos = d->hwirq & 7;
@@ -350,7 +345,7 @@ static void adnp_irq_mask(struct irq_data *d)
static void adnp_irq_unmask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct adnp *adnp = to_adnp(gc);
struct adnp *adnp = gpiochip_get_data(gc);
unsigned int reg = d->hwirq >> adnp->reg_shift;
unsigned int pos = d->hwirq & 7;
@@ -360,7 +355,7 @@ static void adnp_irq_unmask(struct irq_data *d)
static int adnp_irq_set_type(struct irq_data *d, unsigned int type)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct adnp *adnp = to_adnp(gc);
struct adnp *adnp = gpiochip_get_data(gc);
unsigned int reg = d->hwirq >> adnp->reg_shift;
unsigned int pos = d->hwirq & 7;
@@ -390,7 +385,7 @@ static int adnp_irq_set_type(struct irq_data *d, unsigned int type)
static void adnp_irq_bus_lock(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct adnp *adnp = to_adnp(gc);
struct adnp *adnp = gpiochip_get_data(gc);
mutex_lock(&adnp->irq_lock);
}
@@ -398,7 +393,7 @@ static void adnp_irq_bus_lock(struct irq_data *d)
static void adnp_irq_bus_unlock(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct adnp *adnp = to_adnp(gc);
struct adnp *adnp = gpiochip_get_data(gc);
unsigned int num_regs = 1 << adnp->reg_shift, i;
mutex_lock(&adnp->i2c_lock);
@@ -435,7 +430,8 @@ static int adnp_irq_setup(struct adnp *adnp)
* is chosen to match the register layout of the hardware in that
* each segment contains the corresponding bits for all interrupts.
*/
adnp->irq_enable = devm_kzalloc(chip->dev, num_regs * 6, GFP_KERNEL);
adnp->irq_enable = devm_kzalloc(chip->parent, num_regs * 6,
GFP_KERNEL);
if (!adnp->irq_enable)
return -ENOMEM;
@@ -462,12 +458,12 @@ static int adnp_irq_setup(struct adnp *adnp)
adnp->irq_enable[i] = 0x00;
}
err = devm_request_threaded_irq(chip->dev, adnp->client->irq,
err = devm_request_threaded_irq(chip->parent, adnp->client->irq,
NULL, adnp_irq,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
dev_name(chip->dev), adnp);
dev_name(chip->parent), adnp);
if (err != 0) {
dev_err(chip->dev, "can't request IRQ#%d: %d\n",
dev_err(chip->parent, "can't request IRQ#%d: %d\n",
adnp->client->irq, err);
return err;
}
@@ -478,7 +474,7 @@ static int adnp_irq_setup(struct adnp *adnp)
handle_simple_irq,
IRQ_TYPE_NONE);
if (err) {
dev_err(chip->dev,
dev_err(chip->parent,
"could not connect irqchip to gpiochip\n");
return err;
}
@@ -547,7 +543,6 @@ MODULE_DEVICE_TABLE(of, adnp_of_match);
static struct i2c_driver adnp_i2c_driver = {
.driver = {
.name = "gpio-adnp",
.owner = THIS_MODULE,
.of_match_table = adnp_of_match,
},
.probe = adnp_i2c_probe,

View File

@@ -27,7 +27,7 @@ static int adp5520_gpio_get_value(struct gpio_chip *chip, unsigned off)
struct adp5520_gpio *dev;
uint8_t reg_val;
dev = container_of(chip, struct adp5520_gpio, gpio_chip);
dev = gpiochip_get_data(chip);
/*
* There are dedicated registers for GPIO IN/OUT.
@@ -46,7 +46,7 @@ static void adp5520_gpio_set_value(struct gpio_chip *chip,
unsigned off, int val)
{
struct adp5520_gpio *dev;
dev = container_of(chip, struct adp5520_gpio, gpio_chip);
dev = gpiochip_get_data(chip);
if (val)
adp5520_set_bits(dev->master, ADP5520_GPIO_OUT, dev->lut[off]);
@@ -57,7 +57,7 @@ static void adp5520_gpio_set_value(struct gpio_chip *chip,
static int adp5520_gpio_direction_input(struct gpio_chip *chip, unsigned off)
{
struct adp5520_gpio *dev;
dev = container_of(chip, struct adp5520_gpio, gpio_chip);
dev = gpiochip_get_data(chip);
clear_bit(off, &dev->output);
@@ -70,7 +70,7 @@ static int adp5520_gpio_direction_output(struct gpio_chip *chip,
{
struct adp5520_gpio *dev;
int ret = 0;
dev = container_of(chip, struct adp5520_gpio, gpio_chip);
dev = gpiochip_get_data(chip);
set_bit(off, &dev->output);
@@ -153,7 +153,7 @@ static int adp5520_gpio_probe(struct platform_device *pdev)
goto err;
}
ret = gpiochip_add(&dev->gpio_chip);
ret = gpiochip_add_data(&dev->gpio_chip, dev);
if (ret)
goto err;

View File

@@ -65,8 +65,7 @@ static int adp5588_gpio_write(struct i2c_client *client, u8 reg, u8 val)
static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off)
{
struct adp5588_gpio *dev =
container_of(chip, struct adp5588_gpio, gpio_chip);
struct adp5588_gpio *dev = gpiochip_get_data(chip);
unsigned bank = ADP5588_BANK(off);
unsigned bit = ADP5588_BIT(off);
int val;
@@ -87,8 +86,7 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip,
unsigned off, int val)
{
unsigned bank, bit;
struct adp5588_gpio *dev =
container_of(chip, struct adp5588_gpio, gpio_chip);
struct adp5588_gpio *dev = gpiochip_get_data(chip);
bank = ADP5588_BANK(off);
bit = ADP5588_BIT(off);
@@ -108,8 +106,7 @@ static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off)
{
int ret;
unsigned bank;
struct adp5588_gpio *dev =
container_of(chip, struct adp5588_gpio, gpio_chip);
struct adp5588_gpio *dev = gpiochip_get_data(chip);
bank = ADP5588_BANK(off);
@@ -126,8 +123,7 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip,
{
int ret;
unsigned bank, bit;
struct adp5588_gpio *dev =
container_of(chip, struct adp5588_gpio, gpio_chip);
struct adp5588_gpio *dev = gpiochip_get_data(chip);
bank = ADP5588_BANK(off);
bit = ADP5588_BIT(off);
@@ -152,8 +148,8 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip,
#ifdef CONFIG_GPIO_ADP5588_IRQ
static int adp5588_gpio_to_irq(struct gpio_chip *chip, unsigned off)
{
struct adp5588_gpio *dev =
container_of(chip, struct adp5588_gpio, gpio_chip);
struct adp5588_gpio *dev = gpiochip_get_data(chip);
return dev->irq_base + off;
}
@@ -418,7 +414,7 @@ static int adp5588_gpio_probe(struct i2c_client *client,
}
}
ret = gpiochip_add(&dev->gpio_chip);
ret = gpiochip_add_data(&dev->gpio_chip, dev);
if (ret)
goto err_irq;

Some files were not shown because too many files have changed in this diff Show More