mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge tag 'gpio-updates-for-v6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux
Pull gpio updates from Bartosz Golaszewski:
"We have a lot of code refactoring using common helpers and ended up
removing more lines then we're adding this release cycle.
Nothing really stands out, just small updates all over the place.
Core GPIOLIB updates:
- wake-up poll() in user-space on device unbind
- improve fwnode usage
- interrupt domain handling improvements
- correctly handle the ngpios property in gpio-mmio
Driver cleanups:
- remove unneeded calls to platform_set_drvdata() all around the
place
- remove unneeded of_match_ptr() expansions whenever a driver depends
on CONFIG_OF
- remove redundant calls to dev_err_probe() from gpio-omap and
gpio-davinci
Driver improvements:
- use autopointers and guards from cleanup.h in gpio-sim
- shrink code in gpio-sim using some common helpers
- convert the idio family of drivers to using gpio-regmap
- convert gpio-ws16c48 to using gpio-regmap
- use devres to simplify code in gpio-pisosr and gpio-mxc
- update gpio-sifive: support IRQ wake, improve interrupt handling,
allow building as module
- make gpio-ge and gpio-bcm-kona OF-independent (plus some minor
tweaks)
- add support for new models in gpio-pca953x and gpio-ds4520
- add runtime PM support to gpio-mxc
- fix a build warning in gpio-mxs
- add support for adding pin ranges to gpio-mlxbf3
- add counter/timer support to gpio-104-dio-48e
- switch to dynamic GPIO base allocation in gpio-vf610
- minor oneliners here and there
Device-tree bindings updates:
- enable the gpio-line-names property in snps,dw-apb and STMPE GPIO
- document new models in fsl-imx-gpio, ds4520 and pca95xx
- convert the bindings for brcm,kona-gpio to YAML"
* tag 'gpio-updates-for-v6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux: (94 commits)
gpio: pca953x: add support for TCA9538
dt-bindings: gpio: pca95xx: document new tca9538 chip
gpio: pca953x: Use i2c_get_match_data()
gpio: mlxbf3: use capital "OR" for multiple licenses in SPDX
gpio: pcf857x: Extend match data support for OF tables
gpio: vf610: switch to dynamic allocat GPIO base
gpiolib: provide and use gpiod_line_state_notify()
gpio: cdev: wake up lineevent poll() on device unbind
gpio: cdev: wake up linereq poll() on device unbind
gpio: cdev: wake up chardev poll() on device unbind
gpiolib: add a second blocking notifier to struct gpio_device
gpio: cdev: open-code to_gpio_chardev_data()
gpiolib: rename the gpio_device notifier
gpio: mlxbf3: Support add_pin_ranges()
gpio: mxc: Use helper function devm_clk_get_optional_enabled()
gpio: pca9570: fix kerneldoc
gpio: sim: simplify code with cleanup helpers
gpio: sim: replace memmove() + strstrip() with skip_spaces() + strim()
gpio: sim: simplify gpio_sim_device_config_live_store()
gpio: mxc: release the parent IRQ in runtime suspend
...
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/gpio/adi,ds4520-gpio.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: DS4520 I2C GPIO expander
|
||||
|
||||
maintainers:
|
||||
- Okan Sahin <okan.sahin@analog.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- adi,ds4520-gpio
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
gpio-controller: true
|
||||
|
||||
"#gpio-cells":
|
||||
const: 2
|
||||
|
||||
ngpios:
|
||||
minimum: 1
|
||||
maximum: 9
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- gpio-controller
|
||||
- "#gpio-cells"
|
||||
- ngpios
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
gpio@50 {
|
||||
compatible = "adi,ds4520-gpio";
|
||||
reg = <0x50>;
|
||||
ngpios = <9>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
};
|
||||
@@ -1,52 +0,0 @@
|
||||
Broadcom Kona Family GPIO
|
||||
=========================
|
||||
|
||||
This GPIO driver is used in the following Broadcom SoCs:
|
||||
BCM11130, BCM11140, BCM11351, BCM28145, BCM28155
|
||||
|
||||
The Broadcom GPIO Controller IP can be configured prior to synthesis to
|
||||
support up to 8 banks of 32 GPIOs where each bank has its own IRQ. The
|
||||
GPIO controller only supports edge, not level, triggering of interrupts.
|
||||
|
||||
Required properties
|
||||
-------------------
|
||||
|
||||
- compatible: "brcm,bcm11351-gpio", "brcm,kona-gpio"
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
- interrupts: The interrupt outputs from the controller. There is one GPIO
|
||||
interrupt per GPIO bank. The number of interrupts listed depends on the
|
||||
number of GPIO banks on the SoC. The interrupts must be ordered by bank,
|
||||
starting with bank 0. There is always a 1:1 mapping between banks and
|
||||
IRQs.
|
||||
- #gpio-cells: Should be <2>. The first cell is the pin number, the second
|
||||
cell is used to specify optional parameters:
|
||||
- bit 0 specifies polarity (0 for normal, 1 for inverted)
|
||||
See also "gpio-specifier" in .../devicetree/bindings/gpio/gpio.txt.
|
||||
- #interrupt-cells: Should be <2>. The first cell is the GPIO number. The
|
||||
second cell is used to specify flags. The following subset of flags is
|
||||
supported:
|
||||
- trigger type (bits[1:0]):
|
||||
1 = low-to-high edge triggered.
|
||||
2 = high-to-low edge triggered.
|
||||
3 = low-to-high or high-to-low edge triggered
|
||||
Valid values are 1, 2, 3
|
||||
See also .../devicetree/bindings/interrupt-controller/interrupts.txt.
|
||||
- gpio-controller: Marks the device node as a GPIO controller.
|
||||
- interrupt-controller: Marks the device node as an interrupt controller.
|
||||
|
||||
Example:
|
||||
gpio: gpio@35003000 {
|
||||
compatible = "brcm,bcm11351-gpio", "brcm,kona-gpio";
|
||||
reg = <0x35003000 0x800>;
|
||||
interrupts =
|
||||
<GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH
|
||||
GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH
|
||||
GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH
|
||||
GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
|
||||
GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH
|
||||
GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
|
||||
#gpio-cells = <2>;
|
||||
#interrupt-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
};
|
||||
@@ -0,0 +1,100 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/gpio/brcm,kona-gpio.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Broadcom Kona family GPIO controller
|
||||
|
||||
description:
|
||||
The Broadcom GPIO Controller IP can be configured prior to synthesis to
|
||||
support up to 8 banks of 32 GPIOs where each bank has its own IRQ. The
|
||||
GPIO controller only supports edge, not level, triggering of interrupts.
|
||||
|
||||
maintainers:
|
||||
- Ray Jui <rjui@broadcom.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- brcm,bcm11351-gpio
|
||||
- brcm,bcm21664-gpio
|
||||
- brcm,bcm23550-gpio
|
||||
- const: brcm,kona-gpio
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
minItems: 4
|
||||
maxItems: 6
|
||||
description:
|
||||
The interrupt outputs from the controller. There is one GPIO interrupt
|
||||
per GPIO bank. The number of interrupts listed depends on the number of
|
||||
GPIO banks on the SoC. The interrupts must be ordered by bank, starting
|
||||
with bank 0. There is always a 1:1 mapping between banks and IRQs.
|
||||
|
||||
'#gpio-cells':
|
||||
const: 2
|
||||
|
||||
'#interrupt-cells':
|
||||
const: 2
|
||||
|
||||
gpio-controller: true
|
||||
|
||||
interrupt-controller: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- '#gpio-cells'
|
||||
- '#interrupt-cells'
|
||||
- gpio-controller
|
||||
- interrupt-controller
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: brcm,bcm11351-gpio
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 6
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- brcm,bcm21664-gpio
|
||||
- brcm,bcm23550-gpio
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
maxItems: 4
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
gpio@35003000 {
|
||||
compatible = "brcm,bcm11351-gpio", "brcm,kona-gpio";
|
||||
reg = <0x35003000 0x800>;
|
||||
interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
|
||||
#gpio-cells = <2>;
|
||||
#interrupt-cells = <2>;
|
||||
gpio-controller;
|
||||
interrupt-controller;
|
||||
};
|
||||
...
|
||||
@@ -32,10 +32,12 @@ properties:
|
||||
- fsl,imx6sx-gpio
|
||||
- fsl,imx6ul-gpio
|
||||
- fsl,imx7d-gpio
|
||||
- fsl,imx8dxl-gpio
|
||||
- fsl,imx8mm-gpio
|
||||
- fsl,imx8mn-gpio
|
||||
- fsl,imx8mp-gpio
|
||||
- fsl,imx8mq-gpio
|
||||
- fsl,imx8qm-gpio
|
||||
- fsl,imx8qxp-gpio
|
||||
- fsl,imxrt1050-gpio
|
||||
- fsl,imxrt1170-gpio
|
||||
|
||||
@@ -66,6 +66,7 @@ properties:
|
||||
- ti,tca6408
|
||||
- ti,tca6416
|
||||
- ti,tca6424
|
||||
- ti,tca9538
|
||||
- ti,tca9539
|
||||
- ti,tca9554
|
||||
|
||||
|
||||
@@ -61,6 +61,10 @@ patternProperties:
|
||||
'#gpio-cells':
|
||||
const: 2
|
||||
|
||||
gpio-line-names:
|
||||
minItems: 1
|
||||
maxItems: 32
|
||||
|
||||
ngpios:
|
||||
default: 32
|
||||
minimum: 1
|
||||
|
||||
@@ -28,6 +28,10 @@ properties:
|
||||
|
||||
gpio-controller: true
|
||||
|
||||
gpio-line-names:
|
||||
minItems: 1
|
||||
maxItems: 24
|
||||
|
||||
interrupt-controller: true
|
||||
|
||||
st,norequest-mask:
|
||||
|
||||
+1
-1
@@ -4195,7 +4195,7 @@ BROADCOM KONA GPIO DRIVER
|
||||
M: Ray Jui <rjui@broadcom.com>
|
||||
R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/gpio/brcm,kona-gpio.txt
|
||||
F: Documentation/devicetree/bindings/gpio/brcm,kona-gpio.yaml
|
||||
F: drivers/gpio/gpio-bcm-kona.c
|
||||
|
||||
BROADCOM MPI3 STORAGE CONTROLLER DRIVER
|
||||
|
||||
+26
-5
@@ -111,6 +111,9 @@ config GPIO_MAX730X
|
||||
|
||||
config GPIO_IDIO_16
|
||||
tristate
|
||||
select REGMAP_IRQ
|
||||
select GPIOLIB_IRQCHIP
|
||||
select GPIO_REGMAP
|
||||
help
|
||||
Enables support for the idio-16 library functions. The idio-16 library
|
||||
provides functions to facilitate communication with devices within the
|
||||
@@ -191,7 +194,7 @@ config GPIO_RASPBERRYPI_EXP
|
||||
|
||||
config GPIO_BCM_KONA
|
||||
bool "Broadcom Kona GPIO"
|
||||
depends on OF_GPIO && (ARCH_BCM_MOBILE || COMPILE_TEST)
|
||||
depends on ARCH_BCM_MOBILE || COMPILE_TEST
|
||||
help
|
||||
Turn on GPIO support for Broadcom "Kona" chips.
|
||||
|
||||
@@ -283,7 +286,7 @@ config GPIO_EXAR
|
||||
|
||||
config GPIO_GE_FPGA
|
||||
bool "GE FPGA based GPIO"
|
||||
depends on GE_FPGA
|
||||
depends on GE_FPGA || COMPILE_TEST
|
||||
select GPIO_GENERIC
|
||||
help
|
||||
Support for common GPIO functionality provided on some GE Single Board
|
||||
@@ -564,7 +567,7 @@ config GPIO_SAMA5D2_PIOBU
|
||||
maintain their value during backup/self-refresh.
|
||||
|
||||
config GPIO_SIFIVE
|
||||
bool "SiFive GPIO support"
|
||||
tristate "SiFive GPIO support"
|
||||
depends on OF_GPIO
|
||||
select IRQ_DOMAIN_HIERARCHY
|
||||
select GPIO_GENERIC
|
||||
@@ -858,6 +861,7 @@ config GPIO_104_DIO_48E
|
||||
select REGMAP_IRQ
|
||||
select GPIOLIB_IRQCHIP
|
||||
select GPIO_I8255
|
||||
select I8254
|
||||
help
|
||||
Enables GPIO support for the ACCES 104-DIO-48E series (104-DIO-48E,
|
||||
104-DIO-24E). The base port addresses for the devices may be
|
||||
@@ -868,7 +872,7 @@ config GPIO_104_IDIO_16
|
||||
tristate "ACCES 104-IDIO-16 GPIO support"
|
||||
depends on PC104
|
||||
select ISA_BUS_API
|
||||
select GPIOLIB_IRQCHIP
|
||||
select REGMAP_MMIO
|
||||
select GPIO_IDIO_16
|
||||
help
|
||||
Enables GPIO support for the ACCES 104-IDIO-16 family (104-IDIO-16,
|
||||
@@ -994,7 +998,10 @@ config GPIO_WINBOND
|
||||
config GPIO_WS16C48
|
||||
tristate "WinSystems WS16C48 GPIO support"
|
||||
select ISA_BUS_API
|
||||
select REGMAP_IRQ
|
||||
select REGMAP_MMIO
|
||||
select GPIOLIB_IRQCHIP
|
||||
select GPIO_REGMAP
|
||||
help
|
||||
Enables GPIO support for the WinSystems WS16C48. The base port
|
||||
addresses for the devices may be configured via the base module
|
||||
@@ -1028,6 +1035,17 @@ config GPIO_FXL6408
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called gpio-fxl6408.
|
||||
|
||||
config GPIO_DS4520
|
||||
tristate "DS4520 I2C GPIO expander"
|
||||
select REGMAP_I2C
|
||||
select GPIO_REGMAP
|
||||
help
|
||||
GPIO driver for ADI DS4520 I2C-based GPIO expander.
|
||||
Say yes here to enable the GPIO driver for the ADI DS4520 chip.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called gpio-ds4520.
|
||||
|
||||
config GPIO_GW_PLD
|
||||
tristate "Gateworks PLD GPIO Expander"
|
||||
depends on OF_GPIO
|
||||
@@ -1640,7 +1658,7 @@ config GPIO_PCH
|
||||
|
||||
config GPIO_PCI_IDIO_16
|
||||
tristate "ACCES PCI-IDIO-16 GPIO support"
|
||||
select GPIOLIB_IRQCHIP
|
||||
select REGMAP_MMIO
|
||||
select GPIO_IDIO_16
|
||||
help
|
||||
Enables GPIO support for the ACCES PCI-IDIO-16. An interrupt is
|
||||
@@ -1650,7 +1668,10 @@ config GPIO_PCI_IDIO_16
|
||||
|
||||
config GPIO_PCIE_IDIO_24
|
||||
tristate "ACCES PCIe-IDIO-24 GPIO support"
|
||||
select REGMAP_IRQ
|
||||
select REGMAP_MMIO
|
||||
select GPIOLIB_IRQCHIP
|
||||
select GPIO_REGMAP
|
||||
help
|
||||
Enables GPIO support for the ACCES PCIe-IDIO-24 family (PCIe-IDIO-24,
|
||||
PCIe-IDI-24, PCIe-IDO-24, PCIe-IDIO-12). An interrupt is generated
|
||||
|
||||
@@ -52,6 +52,7 @@ obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o
|
||||
obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o
|
||||
obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o
|
||||
obj-$(CONFIG_GPIO_DLN2) += gpio-dln2.o
|
||||
obj-$(CONFIG_GPIO_DS4520) += gpio-ds4520.o
|
||||
obj-$(CONFIG_GPIO_DWAPB) += gpio-dwapb.o
|
||||
obj-$(CONFIG_GPIO_EIC_SPRD) += gpio-eic-sprd.o
|
||||
obj-$(CONFIG_GPIO_ELKHARTLAKE) += gpio-elkhartlake.o
|
||||
|
||||
+111
-16
@@ -9,6 +9,7 @@
|
||||
#include <linux/bits.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/i8254.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/isa.h>
|
||||
@@ -16,6 +17,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "gpio-i8255.h"
|
||||
@@ -37,6 +39,8 @@ MODULE_PARM_DESC(irq, "ACCES 104-DIO-48E interrupt line numbers");
|
||||
|
||||
#define DIO48E_ENABLE_INTERRUPT 0xB
|
||||
#define DIO48E_DISABLE_INTERRUPT DIO48E_ENABLE_INTERRUPT
|
||||
#define DIO48E_ENABLE_COUNTER_TIMER_ADDRESSING 0xD
|
||||
#define DIO48E_DISABLE_COUNTER_TIMER_ADDRESSING DIO48E_ENABLE_COUNTER_TIMER_ADDRESSING
|
||||
#define DIO48E_CLEAR_INTERRUPT 0xF
|
||||
|
||||
#define DIO48E_NUM_PPI 2
|
||||
@@ -75,18 +79,20 @@ static const struct regmap_access_table dio48e_precious_table = {
|
||||
.yes_ranges = dio48e_precious_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(dio48e_precious_ranges),
|
||||
};
|
||||
static const struct regmap_config dio48e_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.reg_stride = 1,
|
||||
.val_bits = 8,
|
||||
.io_port = true,
|
||||
.max_register = 0xF,
|
||||
.wr_table = &dio48e_wr_table,
|
||||
.rd_table = &dio48e_rd_table,
|
||||
.volatile_table = &dio48e_volatile_table,
|
||||
.precious_table = &dio48e_precious_table,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
.use_raw_spinlock = true,
|
||||
|
||||
static const struct regmap_range pit_wr_ranges[] = {
|
||||
regmap_reg_range(0x0, 0x3),
|
||||
};
|
||||
static const struct regmap_range pit_rd_ranges[] = {
|
||||
regmap_reg_range(0x0, 0x2),
|
||||
};
|
||||
static const struct regmap_access_table pit_wr_table = {
|
||||
.yes_ranges = pit_wr_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(pit_wr_ranges),
|
||||
};
|
||||
static const struct regmap_access_table pit_rd_table = {
|
||||
.yes_ranges = pit_rd_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(pit_rd_ranges),
|
||||
};
|
||||
|
||||
/* only bit 3 on each respective Port C supports interrupts */
|
||||
@@ -102,14 +108,56 @@ static const struct regmap_irq dio48e_regmap_irqs[] = {
|
||||
|
||||
/**
|
||||
* struct dio48e_gpio - GPIO device private data structure
|
||||
* @lock: synchronization lock to prevent I/O race conditions
|
||||
* @map: Regmap for the device
|
||||
* @regs: virtual mapping for device registers
|
||||
* @flags: IRQ flags saved during locking
|
||||
* @irq_mask: Current IRQ mask state on the device
|
||||
*/
|
||||
struct dio48e_gpio {
|
||||
raw_spinlock_t lock;
|
||||
struct regmap *map;
|
||||
void __iomem *regs;
|
||||
unsigned long flags;
|
||||
unsigned int irq_mask;
|
||||
};
|
||||
|
||||
static void dio48e_regmap_lock(void *lock_arg) __acquires(&dio48egpio->lock)
|
||||
{
|
||||
struct dio48e_gpio *const dio48egpio = lock_arg;
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&dio48egpio->lock, flags);
|
||||
dio48egpio->flags = flags;
|
||||
}
|
||||
|
||||
static void dio48e_regmap_unlock(void *lock_arg) __releases(&dio48egpio->lock)
|
||||
{
|
||||
struct dio48e_gpio *const dio48egpio = lock_arg;
|
||||
|
||||
raw_spin_unlock_irqrestore(&dio48egpio->lock, dio48egpio->flags);
|
||||
}
|
||||
|
||||
static void pit_regmap_lock(void *lock_arg) __acquires(&dio48egpio->lock)
|
||||
{
|
||||
struct dio48e_gpio *const dio48egpio = lock_arg;
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&dio48egpio->lock, flags);
|
||||
dio48egpio->flags = flags;
|
||||
|
||||
iowrite8(0x00, dio48egpio->regs + DIO48E_ENABLE_COUNTER_TIMER_ADDRESSING);
|
||||
}
|
||||
|
||||
static void pit_regmap_unlock(void *lock_arg) __releases(&dio48egpio->lock)
|
||||
{
|
||||
struct dio48e_gpio *const dio48egpio = lock_arg;
|
||||
|
||||
ioread8(dio48egpio->regs + DIO48E_DISABLE_COUNTER_TIMER_ADDRESSING);
|
||||
|
||||
raw_spin_unlock_irqrestore(&dio48egpio->lock, dio48egpio->flags);
|
||||
}
|
||||
|
||||
static int dio48e_handle_mask_sync(const int index,
|
||||
const unsigned int mask_buf_def,
|
||||
const unsigned int mask_buf,
|
||||
@@ -176,6 +224,9 @@ static int dio48e_probe(struct device *dev, unsigned int id)
|
||||
struct i8255_regmap_config config = {};
|
||||
void __iomem *regs;
|
||||
struct regmap *map;
|
||||
struct regmap_config dio48e_regmap_config;
|
||||
struct regmap_config pit_regmap_config;
|
||||
struct i8254_regmap_config pit_config;
|
||||
int err;
|
||||
struct regmap_irq_chip *chip;
|
||||
struct dio48e_gpio *dio48egpio;
|
||||
@@ -187,21 +238,58 @@ static int dio48e_probe(struct device *dev, unsigned int id)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
dio48egpio = devm_kzalloc(dev, sizeof(*dio48egpio), GFP_KERNEL);
|
||||
if (!dio48egpio)
|
||||
return -ENOMEM;
|
||||
|
||||
regs = devm_ioport_map(dev, base[id], DIO48E_EXTENT);
|
||||
if (!regs)
|
||||
return -ENOMEM;
|
||||
|
||||
dio48egpio->regs = regs;
|
||||
|
||||
raw_spin_lock_init(&dio48egpio->lock);
|
||||
|
||||
dio48e_regmap_config = (struct regmap_config) {
|
||||
.reg_bits = 8,
|
||||
.reg_stride = 1,
|
||||
.val_bits = 8,
|
||||
.lock = dio48e_regmap_lock,
|
||||
.unlock = dio48e_regmap_unlock,
|
||||
.lock_arg = dio48egpio,
|
||||
.io_port = true,
|
||||
.wr_table = &dio48e_wr_table,
|
||||
.rd_table = &dio48e_rd_table,
|
||||
.volatile_table = &dio48e_volatile_table,
|
||||
.precious_table = &dio48e_precious_table,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
map = devm_regmap_init_mmio(dev, regs, &dio48e_regmap_config);
|
||||
if (IS_ERR(map))
|
||||
return dev_err_probe(dev, PTR_ERR(map),
|
||||
"Unable to initialize register map\n");
|
||||
|
||||
dio48egpio = devm_kzalloc(dev, sizeof(*dio48egpio), GFP_KERNEL);
|
||||
if (!dio48egpio)
|
||||
return -ENOMEM;
|
||||
|
||||
dio48egpio->map = map;
|
||||
|
||||
pit_regmap_config = (struct regmap_config) {
|
||||
.name = "i8254",
|
||||
.reg_bits = 8,
|
||||
.reg_stride = 1,
|
||||
.val_bits = 8,
|
||||
.lock = pit_regmap_lock,
|
||||
.unlock = pit_regmap_unlock,
|
||||
.lock_arg = dio48egpio,
|
||||
.io_port = true,
|
||||
.wr_table = &pit_wr_table,
|
||||
.rd_table = &pit_rd_table,
|
||||
};
|
||||
|
||||
pit_config.map = devm_regmap_init_mmio(dev, regs, &pit_regmap_config);
|
||||
if (IS_ERR(pit_config.map))
|
||||
return dev_err_probe(dev, PTR_ERR(pit_config.map),
|
||||
"Unable to initialize i8254 register map\n");
|
||||
|
||||
chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
|
||||
if (!chip)
|
||||
return -ENOMEM;
|
||||
@@ -225,6 +313,12 @@ static int dio48e_probe(struct device *dev, unsigned int id)
|
||||
if (err)
|
||||
return dev_err_probe(dev, err, "IRQ registration failed\n");
|
||||
|
||||
pit_config.parent = dev;
|
||||
|
||||
err = devm_i8254_regmap_register(dev, &pit_config);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
config.parent = dev;
|
||||
config.map = map;
|
||||
config.num_ppi = DIO48E_NUM_PPI;
|
||||
@@ -245,3 +339,4 @@ module_isa_driver_with_irq(dio48e_driver, num_dio48e, num_irq);
|
||||
MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
|
||||
MODULE_DESCRIPTION("ACCES 104-DIO-48E GPIO driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_IMPORT_NS(I8254);
|
||||
|
||||
+63
-223
@@ -6,19 +6,16 @@
|
||||
* This driver supports the following ACCES devices: 104-IDIO-16,
|
||||
* 104-IDIO-16E, 104-IDO-16, 104-IDIO-8, 104-IDIO-8E, and 104-IDO-8.
|
||||
*/
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irqdesc.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/isa.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "gpio-idio-16.h"
|
||||
@@ -36,187 +33,62 @@ static unsigned int num_irq;
|
||||
module_param_hw_array(irq, uint, irq, &num_irq, 0);
|
||||
MODULE_PARM_DESC(irq, "ACCES 104-IDIO-16 interrupt line numbers");
|
||||
|
||||
/**
|
||||
* struct idio_16_gpio - GPIO device private data structure
|
||||
* @chip: instance of the gpio_chip
|
||||
* @lock: synchronization lock to prevent I/O race conditions
|
||||
* @irq_mask: I/O bits affected by interrupts
|
||||
* @reg: I/O address offset for the device registers
|
||||
* @state: ACCES IDIO-16 device state
|
||||
*/
|
||||
struct idio_16_gpio {
|
||||
struct gpio_chip chip;
|
||||
raw_spinlock_t lock;
|
||||
unsigned long irq_mask;
|
||||
struct idio_16 __iomem *reg;
|
||||
struct idio_16_state state;
|
||||
static const struct regmap_range idio_16_wr_ranges[] = {
|
||||
regmap_reg_range(0x0, 0x2), regmap_reg_range(0x4, 0x4),
|
||||
};
|
||||
static const struct regmap_range idio_16_rd_ranges[] = {
|
||||
regmap_reg_range(0x1, 0x2), regmap_reg_range(0x5, 0x5),
|
||||
};
|
||||
static const struct regmap_range idio_16_precious_ranges[] = {
|
||||
regmap_reg_range(0x2, 0x2),
|
||||
};
|
||||
static const struct regmap_access_table idio_16_wr_table = {
|
||||
.yes_ranges = idio_16_wr_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(idio_16_wr_ranges),
|
||||
};
|
||||
static const struct regmap_access_table idio_16_rd_table = {
|
||||
.yes_ranges = idio_16_rd_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(idio_16_rd_ranges),
|
||||
};
|
||||
static const struct regmap_access_table idio_16_precious_table = {
|
||||
.yes_ranges = idio_16_precious_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(idio_16_precious_ranges),
|
||||
};
|
||||
static const struct regmap_config idio_16_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.reg_stride = 1,
|
||||
.val_bits = 8,
|
||||
.io_port = true,
|
||||
.wr_table = &idio_16_wr_table,
|
||||
.rd_table = &idio_16_rd_table,
|
||||
.volatile_table = &idio_16_rd_table,
|
||||
.precious_table = &idio_16_precious_table,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
.use_raw_spinlock = true,
|
||||
};
|
||||
|
||||
static int idio_16_gpio_get_direction(struct gpio_chip *chip,
|
||||
unsigned int offset)
|
||||
{
|
||||
if (idio_16_get_direction(offset))
|
||||
return GPIO_LINE_DIRECTION_IN;
|
||||
|
||||
return GPIO_LINE_DIRECTION_OUT;
|
||||
}
|
||||
|
||||
static int idio_16_gpio_direction_input(struct gpio_chip *chip,
|
||||
unsigned int offset)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int idio_16_gpio_direction_output(struct gpio_chip *chip,
|
||||
unsigned int offset, int value)
|
||||
{
|
||||
chip->set(chip, offset, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset)
|
||||
{
|
||||
struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
|
||||
|
||||
return idio_16_get(idio16gpio->reg, &idio16gpio->state, offset);
|
||||
}
|
||||
|
||||
static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
|
||||
unsigned long *mask, unsigned long *bits)
|
||||
{
|
||||
struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
|
||||
|
||||
idio_16_get_multiple(idio16gpio->reg, &idio16gpio->state, mask, bits);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset,
|
||||
int value)
|
||||
{
|
||||
struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
|
||||
|
||||
idio_16_set(idio16gpio->reg, &idio16gpio->state, offset, value);
|
||||
}
|
||||
|
||||
static void idio_16_gpio_set_multiple(struct gpio_chip *chip,
|
||||
unsigned long *mask, unsigned long *bits)
|
||||
{
|
||||
struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
|
||||
|
||||
idio_16_set_multiple(idio16gpio->reg, &idio16gpio->state, mask, bits);
|
||||
}
|
||||
|
||||
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 offset = irqd_to_hwirq(data);
|
||||
unsigned long flags;
|
||||
|
||||
idio16gpio->irq_mask &= ~BIT(offset);
|
||||
gpiochip_disable_irq(chip, offset);
|
||||
|
||||
if (!idio16gpio->irq_mask) {
|
||||
raw_spin_lock_irqsave(&idio16gpio->lock, flags);
|
||||
|
||||
iowrite8(0, &idio16gpio->reg->irq_ctl);
|
||||
|
||||
raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
|
||||
/* Only input lines (GPIO 16-31) support interrupts */
|
||||
#define IDIO_16_REGMAP_IRQ(_id) \
|
||||
[16 + _id] = { \
|
||||
.mask = BIT(_id), \
|
||||
.type = { .types_supported = IRQ_TYPE_EDGE_BOTH }, \
|
||||
}
|
||||
}
|
||||
|
||||
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 offset = irqd_to_hwirq(data);
|
||||
const unsigned long prev_irq_mask = idio16gpio->irq_mask;
|
||||
unsigned long flags;
|
||||
|
||||
gpiochip_enable_irq(chip, offset);
|
||||
idio16gpio->irq_mask |= BIT(offset);
|
||||
|
||||
if (!prev_irq_mask) {
|
||||
raw_spin_lock_irqsave(&idio16gpio->lock, flags);
|
||||
|
||||
ioread8(&idio16gpio->reg->irq_ctl);
|
||||
|
||||
raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
static int idio_16_irq_set_type(struct irq_data *data, unsigned int 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 const 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,
|
||||
.flags = IRQCHIP_IMMUTABLE,
|
||||
GPIOCHIP_IRQ_RESOURCE_HELPERS,
|
||||
static const struct regmap_irq idio_16_regmap_irqs[] = {
|
||||
IDIO_16_REGMAP_IRQ(0), IDIO_16_REGMAP_IRQ(1), IDIO_16_REGMAP_IRQ(2), /* 0-2 */
|
||||
IDIO_16_REGMAP_IRQ(3), IDIO_16_REGMAP_IRQ(4), IDIO_16_REGMAP_IRQ(5), /* 3-5 */
|
||||
IDIO_16_REGMAP_IRQ(6), IDIO_16_REGMAP_IRQ(7), IDIO_16_REGMAP_IRQ(8), /* 6-8 */
|
||||
IDIO_16_REGMAP_IRQ(9), IDIO_16_REGMAP_IRQ(10), IDIO_16_REGMAP_IRQ(11), /* 9-11 */
|
||||
IDIO_16_REGMAP_IRQ(12), IDIO_16_REGMAP_IRQ(13), IDIO_16_REGMAP_IRQ(14), /* 12-14 */
|
||||
IDIO_16_REGMAP_IRQ(15), /* 15 */
|
||||
};
|
||||
|
||||
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_domain_irq(chip->irq.domain, gpio);
|
||||
|
||||
raw_spin_lock(&idio16gpio->lock);
|
||||
|
||||
iowrite8(0, &idio16gpio->reg->in0_7);
|
||||
|
||||
raw_spin_unlock(&idio16gpio->lock);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
#define IDIO_16_NGPIO 32
|
||||
static const char *idio_16_names[IDIO_16_NGPIO] = {
|
||||
"OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
|
||||
"OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
|
||||
"IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
|
||||
"IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15"
|
||||
};
|
||||
|
||||
static int idio_16_irq_init_hw(struct gpio_chip *gc)
|
||||
{
|
||||
struct idio_16_gpio *const idio16gpio = gpiochip_get_data(gc);
|
||||
|
||||
/* Disable IRQ by default */
|
||||
iowrite8(0, &idio16gpio->reg->irq_ctl);
|
||||
iowrite8(0, &idio16gpio->reg->in0_7);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int idio_16_probe(struct device *dev, unsigned int id)
|
||||
{
|
||||
struct idio_16_gpio *idio16gpio;
|
||||
const char *const name = dev_name(dev);
|
||||
struct gpio_irq_chip *girq;
|
||||
int err;
|
||||
|
||||
idio16gpio = devm_kzalloc(dev, sizeof(*idio16gpio), GFP_KERNEL);
|
||||
if (!idio16gpio)
|
||||
return -ENOMEM;
|
||||
struct idio_16_regmap_config config = {};
|
||||
void __iomem *regs;
|
||||
struct regmap *map;
|
||||
|
||||
if (!devm_request_region(dev, base[id], IDIO_16_EXTENT, name)) {
|
||||
dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
|
||||
@@ -224,54 +96,22 @@ static int idio_16_probe(struct device *dev, unsigned int id)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
idio16gpio->reg = devm_ioport_map(dev, base[id], IDIO_16_EXTENT);
|
||||
if (!idio16gpio->reg)
|
||||
regs = devm_ioport_map(dev, base[id], IDIO_16_EXTENT);
|
||||
if (!regs)
|
||||
return -ENOMEM;
|
||||
|
||||
idio16gpio->chip.label = name;
|
||||
idio16gpio->chip.parent = dev;
|
||||
idio16gpio->chip.owner = THIS_MODULE;
|
||||
idio16gpio->chip.base = -1;
|
||||
idio16gpio->chip.ngpio = IDIO_16_NGPIO;
|
||||
idio16gpio->chip.names = idio_16_names;
|
||||
idio16gpio->chip.get_direction = idio_16_gpio_get_direction;
|
||||
idio16gpio->chip.direction_input = idio_16_gpio_direction_input;
|
||||
idio16gpio->chip.direction_output = idio_16_gpio_direction_output;
|
||||
idio16gpio->chip.get = idio_16_gpio_get;
|
||||
idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple;
|
||||
idio16gpio->chip.set = idio_16_gpio_set;
|
||||
idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple;
|
||||
map = devm_regmap_init_mmio(dev, regs, &idio_16_regmap_config);
|
||||
if (IS_ERR(map))
|
||||
return dev_err_probe(dev, PTR_ERR(map), "Unable to initialize register map\n");
|
||||
|
||||
idio_16_state_init(&idio16gpio->state);
|
||||
/* FET off states are represented by bit values of "1" */
|
||||
bitmap_fill(idio16gpio->state.out_state, IDIO_16_NOUT);
|
||||
config.parent = dev;
|
||||
config.map = map;
|
||||
config.regmap_irqs = idio_16_regmap_irqs;
|
||||
config.num_regmap_irqs = ARRAY_SIZE(idio_16_regmap_irqs);
|
||||
config.irq = irq[id];
|
||||
config.no_status = true;
|
||||
|
||||
girq = &idio16gpio->chip.irq;
|
||||
gpio_irq_chip_set_chip(girq, &idio_16_irqchip);
|
||||
/* This will let us handle the parent IRQ in the driver */
|
||||
girq->parent_handler = NULL;
|
||||
girq->num_parents = 0;
|
||||
girq->parents = NULL;
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
girq->handler = handle_edge_irq;
|
||||
girq->init_hw = idio_16_irq_init_hw;
|
||||
|
||||
raw_spin_lock_init(&idio16gpio->lock);
|
||||
|
||||
err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio);
|
||||
if (err) {
|
||||
dev_err(dev, "GPIO registering failed (%d)\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = devm_request_irq(dev, irq[id], idio_16_irq_handler, 0, name,
|
||||
idio16gpio);
|
||||
if (err) {
|
||||
dev_err(dev, "IRQ handler registering failed (%d)\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return devm_idio_16_regmap_register(dev, &config);
|
||||
}
|
||||
|
||||
static struct isa_driver idio_16_driver = {
|
||||
|
||||
@@ -135,8 +135,6 @@ static int mmio_74xx_gpio_probe(struct platform_device *pdev)
|
||||
priv->gc.ngpio = MMIO_74XX_BIT_CNT(priv->flags);
|
||||
priv->gc.owner = THIS_MODULE;
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
return devm_gpiochip_add_data(&pdev->dev, &priv->gc, priv);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/mfd/altera-a10sr.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/property.h>
|
||||
|
||||
@@ -104,7 +105,7 @@ static struct platform_driver altr_a10sr_gpio_driver = {
|
||||
.probe = altr_a10sr_gpio_probe,
|
||||
.driver = {
|
||||
.name = "altr_a10sr_gpio",
|
||||
.of_match_table = of_match_ptr(altr_a10sr_gpio_of_match),
|
||||
.of_match_table = altr_a10sr_gpio_of_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(altr_a10sr_gpio_driver);
|
||||
|
||||
@@ -9,8 +9,9 @@
|
||||
*/
|
||||
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/platform_data/gpio-ath79.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
@@ -8,12 +8,14 @@
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/irqchip/chained_irq.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
|
||||
#define BCM_GPIO_PASSWD 0x00a5a501
|
||||
#define GPIO_PER_BANK 32
|
||||
@@ -62,7 +64,6 @@ struct bcm_kona_gpio {
|
||||
struct gpio_chip gpio_chip;
|
||||
struct irq_domain *irq_domain;
|
||||
struct bcm_kona_gpio_bank *banks;
|
||||
struct platform_device *pdev;
|
||||
};
|
||||
|
||||
struct bcm_kona_gpio_bank {
|
||||
@@ -556,19 +557,12 @@ static void bcm_kona_gpio_reset(struct bcm_kona_gpio *kona_gpio)
|
||||
static int bcm_kona_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
const struct of_device_id *match;
|
||||
struct bcm_kona_gpio_bank *bank;
|
||||
struct bcm_kona_gpio *kona_gpio;
|
||||
struct gpio_chip *chip;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
match = of_match_device(bcm_kona_gpio_of_match, dev);
|
||||
if (!match) {
|
||||
dev_err(dev, "Failed to find gpio controller\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
kona_gpio = devm_kzalloc(dev, sizeof(*kona_gpio), GFP_KERNEL);
|
||||
if (!kona_gpio)
|
||||
return -ENOMEM;
|
||||
@@ -596,15 +590,13 @@ static int bcm_kona_gpio_probe(struct platform_device *pdev)
|
||||
if (!kona_gpio->banks)
|
||||
return -ENOMEM;
|
||||
|
||||
kona_gpio->pdev = pdev;
|
||||
platform_set_drvdata(pdev, kona_gpio);
|
||||
chip->parent = dev;
|
||||
chip->ngpio = kona_gpio->num_bank * GPIO_PER_BANK;
|
||||
|
||||
kona_gpio->irq_domain = irq_domain_add_linear(dev->of_node,
|
||||
chip->ngpio,
|
||||
&bcm_kona_irq_ops,
|
||||
kona_gpio);
|
||||
kona_gpio->irq_domain = irq_domain_create_linear(dev_fwnode(dev),
|
||||
chip->ngpio,
|
||||
&bcm_kona_irq_ops,
|
||||
kona_gpio);
|
||||
if (!kona_gpio->irq_domain) {
|
||||
dev_err(dev, "Couldn't allocate IRQ domain\n");
|
||||
return -ENXIO;
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/irqchip/chained_irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
enum gio_reg_index {
|
||||
GIO_REG_ODEN = 0,
|
||||
|
||||
@@ -67,7 +67,7 @@ static int clps711x_gpio_probe(struct platform_device *pdev)
|
||||
return devm_gpiochip_add_data(&pdev->dev, gc, NULL);
|
||||
}
|
||||
|
||||
static const struct of_device_id __maybe_unused clps711x_gpio_ids[] = {
|
||||
static const struct of_device_id clps711x_gpio_ids[] = {
|
||||
{ .compatible = "cirrus,ep7209-gpio" },
|
||||
{ }
|
||||
};
|
||||
@@ -76,7 +76,7 @@ MODULE_DEVICE_TABLE(of, clps711x_gpio_ids);
|
||||
static struct platform_driver clps711x_gpio_driver = {
|
||||
.driver = {
|
||||
.name = "clps711x-gpio",
|
||||
.of_match_table = of_match_ptr(clps711x_gpio_ids),
|
||||
.of_match_table = clps711x_gpio_ids,
|
||||
},
|
||||
.probe = clps711x_gpio_probe,
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#define MAX_GPIO 32
|
||||
|
||||
|
||||
@@ -236,7 +236,7 @@ static int davinci_gpio_probe(struct platform_device *pdev)
|
||||
for (i = 0; i < nirq; i++) {
|
||||
chips->irqs[i] = platform_get_irq(pdev, i);
|
||||
if (chips->irqs[i] < 0)
|
||||
return dev_err_probe(dev, chips->irqs[i], "IRQ not populated\n");
|
||||
return chips->irqs[i];
|
||||
}
|
||||
|
||||
chips->chip.label = dev_name(dev);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user