mirror of
https://github.com/armbian/linux-cix.git
synced 2026-01-06 12:30:45 -08:00
Merge tag 'gpio-v3.18-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio
Pull GPIO changes from Linus Walleij:
"This is the bulk of GPIO changes for the v3.18 development cycle:
- Increase the default ARCH_NR_GPIO from 256 to 512. This was done
to avoid having a custom <asm/gpio.h> header for the x86
architecture - GPIO is custom and complicated enough as it is
already! We want to move to a radix to store the descriptors going
forward, and finally get rid of this fixed array size altogether.
- Endgame patching of the gpio_remove() semantics initiated by
Abdoulaye Berthe. It is not accepted by the system that the
removal of a GPIO chip fails during eg reboot or shutdown, and
therefore the return value has now painfully been refactored away.
For special cases like GPIO expanders on a hot-pluggable bus like
USB, we may later add some gpiochip_try_remove() call, but for the
cases we have now, return values are moot.
- Some incremental refactoring of the gpiolib core and ACPI GPIO
library for more descriptor usage.
- Refactor the chained IRQ handler set-up method to handle also
threaded, nested interrupts and set up the parent IRQ correctly.
Switch STMPE and TC3589x drivers to use this registration method.
- Add a .irq_not_threaded flag to the struct gpio_chip, so that also
GPIO expanders that block but are still not using threaded IRQ
handlers.
- New drivers for the ARM64 X-Gene SoC GPIO controller.
- The syscon GPIO driver has been improved to handle the "DSP GPIO"
found on the TI Keystone 2 SoC:s.
- ADNP driver switched to use gpiolib irqchip helpers.
- Refactor the DWAPB driver to support being instantiated from and
MFD cell (platform device).
- Incremental feature improvement in the Zynq, MCP23S08, DWAPB, OMAP,
Xilinx and Crystalcove drivers.
- Various minor fixes"
* tag 'gpio-v3.18-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: (52 commits)
gpio: pch: Build context save/restore only for PM
pinctrl: abx500: get rid of unused variable
gpio: ks8695: fix 'else should follow close brace '}''
gpio: stmpe: add verbose debug code
gpio: stmpe: fix up interrupt enable logic
gpio: staticize xway_stp_init()
gpio: handle also nested irqchips in the chained handler set-up
gpio: set parent irq on chained handlers
gpiolib: irqchip: use irq_find_mapping while removing irqchip
gpio: crystalcove: support virtual GPIO
pinctrl: bcm281xx: make Kconfig dependency more strict
gpio: kona: enable only on BCM_MOBILE or for compile testing
gpio, bcm-kona, LLVMLinux: Remove use of __initconst
gpio: Fix ngpio in gpio-xilinx driver
gpio: dwapb: fix pointer to integer cast
gpio: xgene: Remove unneeded #ifdef CONFIG_OF guard
gpio: xgene: Remove unneeded forward declation for struct xgene_gpio
gpio: xgene: Fix missing spin_lock_init()
gpio: ks8695: fix switch case indentation
gpiolib: add irq_not_threaded flag to gpio_chip
...
This commit is contained in:
39
Documentation/devicetree/bindings/gpio/gpio-dsp-keystone.txt
Normal file
39
Documentation/devicetree/bindings/gpio/gpio-dsp-keystone.txt
Normal file
@@ -0,0 +1,39 @@
|
||||
Keystone 2 DSP GPIO controller bindings
|
||||
|
||||
HOST OS userland running on ARM can send interrupts to DSP cores using
|
||||
the DSP GPIO controller IP. It provides 28 IRQ signals per each DSP core.
|
||||
This is one of the component used by the IPC mechanism used on Keystone SOCs.
|
||||
|
||||
For example TCI6638K2K SoC has 8 DSP GPIO controllers:
|
||||
- 8 for C66x CorePacx CPUs 0-7
|
||||
|
||||
Keystone 2 DSP GPIO controller has specific features:
|
||||
- each GPIO can be configured only as output pin;
|
||||
- setting GPIO value to 1 causes IRQ generation on target DSP core;
|
||||
- reading pin value returns 0 - if IRQ was handled or 1 - IRQ is still
|
||||
pending.
|
||||
|
||||
Required Properties:
|
||||
- compatible: should be "ti,keystone-dsp-gpio"
|
||||
- ti,syscon-dev: phandle/offset pair. The phandle to syscon used to
|
||||
access device state control registers and the offset of device's specific
|
||||
registers within device state control registers range.
|
||||
- gpio-controller: Marks the device node as a gpio controller.
|
||||
- #gpio-cells: Should be 2.
|
||||
|
||||
Please refer to gpio.txt in this directory for details of the common GPIO
|
||||
bindings used by client devices.
|
||||
|
||||
Example:
|
||||
dspgpio0: keystone_dsp_gpio@02620240 {
|
||||
compatible = "ti,keystone-dsp-gpio";
|
||||
ti,syscon-dev = <&devctrl 0x240>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
dsp0: dsp0 {
|
||||
compatible = "linux,rproc-user";
|
||||
...
|
||||
kick-gpio = <&dspgpio0 27>;
|
||||
};
|
||||
39
Documentation/devicetree/bindings/gpio/gpio-pca953x.txt
Normal file
39
Documentation/devicetree/bindings/gpio/gpio-pca953x.txt
Normal file
@@ -0,0 +1,39 @@
|
||||
* NXP PCA953x I2C GPIO multiplexer
|
||||
|
||||
Required properties:
|
||||
- compatible: Has to contain one of the following:
|
||||
nxp,pca9505
|
||||
nxp,pca9534
|
||||
nxp,pca9535
|
||||
nxp,pca9536
|
||||
nxp,pca9537
|
||||
nxp,pca9538
|
||||
nxp,pca9539
|
||||
nxp,pca9554
|
||||
nxp,pca9555
|
||||
nxp,pca9556
|
||||
nxp,pca9557
|
||||
nxp,pca9574
|
||||
nxp,pca9575
|
||||
nxp,pca9698
|
||||
maxim,max7310
|
||||
maxim,max7312
|
||||
maxim,max7313
|
||||
maxim,max7315
|
||||
ti,pca6107
|
||||
ti,tca6408
|
||||
ti,tca6416
|
||||
ti,tca6424
|
||||
exar,xra1202
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
gpio@20 {
|
||||
compatible = "nxp,pca9505";
|
||||
reg = <0x20>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pca9505>;
|
||||
interrupt-parent = <&gpio3>;
|
||||
interrupts = <23 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
22
Documentation/devicetree/bindings/gpio/gpio-xgene.txt
Normal file
22
Documentation/devicetree/bindings/gpio/gpio-xgene.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
APM X-Gene SoC GPIO controller bindings
|
||||
|
||||
This is a gpio controller that is part of the flash controller.
|
||||
This gpio controller controls a total of 48 gpios.
|
||||
|
||||
Required properties:
|
||||
- compatible: "apm,xgene-gpio" for X-Gene GPIO controller
|
||||
- reg: Physical base address and size of the controller's registers
|
||||
- #gpio-cells: Should be two.
|
||||
- first cell is the pin number
|
||||
- second cell is used to specify the gpio polarity:
|
||||
0 = active high
|
||||
1 = active low
|
||||
- gpio-controller: Marks the device node as a GPIO controller.
|
||||
|
||||
Example:
|
||||
gpio0: gpio0@1701c000 {
|
||||
compatible = "apm,xgene-gpio";
|
||||
reg = <0x0 0x1701c000 0x0 0x40>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
@@ -19,7 +19,7 @@ Required properties:
|
||||
- gpio-controller : Marks the device node as a gpio controller.
|
||||
- #gpio-cells : Should be one. It is the pin number.
|
||||
|
||||
Example:
|
||||
Example for a MMP platform:
|
||||
|
||||
gpio: gpio@d4019000 {
|
||||
compatible = "marvell,mmp-gpio";
|
||||
@@ -32,6 +32,19 @@ Example:
|
||||
#interrupt-cells = <1>;
|
||||
};
|
||||
|
||||
Example for a PXA3xx platform:
|
||||
|
||||
gpio: gpio@40e00000 {
|
||||
compatible = "intel,pxa3xx-gpio";
|
||||
reg = <0x40e00000 0x10000>;
|
||||
interrupt-names = "gpio0", "gpio1", "gpio_mux";
|
||||
interrupts = <8 9 10>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <0x2>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <0x2>;
|
||||
};
|
||||
|
||||
* Marvell Orion GPIO Controller
|
||||
|
||||
Required properties:
|
||||
|
||||
@@ -124,7 +124,8 @@ symbol:
|
||||
* 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.
|
||||
parent irqchip!) This is for the chained type of chip. This is also used
|
||||
to set up a nested irqchip if NULL is passed as handler.
|
||||
|
||||
To use the helpers please keep the following in mind:
|
||||
|
||||
@@ -178,7 +179,8 @@ does not help since it pins the module to the kernel forever (it calls
|
||||
try_module_get()). A GPIO driver can use the following functions instead
|
||||
to request and free descriptors without being pinned to the kernel forever.
|
||||
|
||||
int gpiochip_request_own_desc(struct gpio_desc *desc, const char *label)
|
||||
struct gpio_desc *gpiochip_request_own_desc(struct gpio_desc *desc,
|
||||
const char *label)
|
||||
|
||||
void gpiochip_free_own_desc(struct gpio_desc *desc)
|
||||
|
||||
|
||||
@@ -243,18 +243,12 @@ err_ioremap:
|
||||
static int scoop_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct scoop_dev *sdev = platform_get_drvdata(pdev);
|
||||
int ret;
|
||||
|
||||
if (!sdev)
|
||||
return -EINVAL;
|
||||
|
||||
if (sdev->gpio.base != -1) {
|
||||
ret = gpiochip_remove(&sdev->gpio);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Can't remove gpio chip: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (sdev->gpio.base != -1)
|
||||
gpiochip_remove(&sdev->gpio);
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
iounmap(sdev->base);
|
||||
|
||||
@@ -789,11 +789,11 @@ void __init txx9_iocled_init(unsigned long baseaddr,
|
||||
if (platform_device_add(pdev))
|
||||
goto out_pdev;
|
||||
return;
|
||||
|
||||
out_pdev:
|
||||
platform_device_put(pdev);
|
||||
out_gpio:
|
||||
if (gpiochip_remove(&iocled->chip))
|
||||
return;
|
||||
gpiochip_remove(&iocled->chip);
|
||||
out_unmap:
|
||||
iounmap(iocled->mmioaddr);
|
||||
out_free:
|
||||
|
||||
@@ -141,7 +141,8 @@ static int mcu_gpiochip_add(struct mcu *mcu)
|
||||
|
||||
static int mcu_gpiochip_remove(struct mcu *mcu)
|
||||
{
|
||||
return gpiochip_remove(&mcu->gc);
|
||||
gpiochip_remove(&mcu->gc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mcu_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
|
||||
@@ -128,10 +128,8 @@ int __init x3proto_gpio_setup(void)
|
||||
return 0;
|
||||
|
||||
err_irq:
|
||||
ret = gpiochip_remove(&x3proto_gpio_chip);
|
||||
if (unlikely(ret))
|
||||
pr_err("Failed deregistering GPIO\n");
|
||||
|
||||
gpiochip_remove(&x3proto_gpio_chip);
|
||||
ret = 0;
|
||||
err_gpio:
|
||||
synchronize_irq(ilsel);
|
||||
|
||||
|
||||
@@ -255,5 +255,6 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
|
||||
int bcma_gpio_unregister(struct bcma_drv_cc *cc)
|
||||
{
|
||||
bcma_gpio_irq_domain_exit(cc);
|
||||
return gpiochip_remove(&cc->gpio);
|
||||
gpiochip_remove(&cc->gpio);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -136,7 +136,6 @@ config GPIO_DWAPB
|
||||
tristate "Synopsys DesignWare APB GPIO driver"
|
||||
select GPIO_GENERIC
|
||||
select GENERIC_IRQ_CHIP
|
||||
depends on OF_GPIO
|
||||
help
|
||||
Say Y or M here to build support for the Synopsys DesignWare APB
|
||||
GPIO block.
|
||||
@@ -334,6 +333,15 @@ config GPIO_TZ1090_PDC
|
||||
help
|
||||
Say yes here to support Toumaz Xenif TZ1090 PDC GPIOs.
|
||||
|
||||
config GPIO_XGENE
|
||||
bool "APM X-Gene GPIO controller support"
|
||||
depends on ARM64 && OF_GPIO
|
||||
help
|
||||
This driver is to support the GPIO block within the APM X-Gene SoC
|
||||
platform's generic flash controller. The GPIO pins are muxed with
|
||||
the generic flash controller's address and data pins. Say yes
|
||||
here to enable the GFC GPIO functionality.
|
||||
|
||||
config GPIO_XILINX
|
||||
bool "Xilinx GPIO support"
|
||||
depends on PPC_OF || MICROBLAZE || ARCH_ZYNQ
|
||||
@@ -681,6 +689,7 @@ config GPIO_ADP5588_IRQ
|
||||
config GPIO_ADNP
|
||||
tristate "Avionic Design N-bit GPIO expander"
|
||||
depends on I2C && OF_GPIO
|
||||
select GPIOLIB_IRQCHIP
|
||||
help
|
||||
This option enables support for N GPIOs found on Avionic Design
|
||||
I2C GPIO expanders. The register space will be extended by powers
|
||||
@@ -796,7 +805,6 @@ config GPIO_MAX7301
|
||||
|
||||
config GPIO_MCP23S08
|
||||
tristate "Microchip MCP23xxx I/O expander"
|
||||
depends on OF_GPIO
|
||||
depends on (SPI_MASTER && !I2C) || I2C
|
||||
help
|
||||
SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017
|
||||
@@ -880,7 +888,7 @@ config GPIO_MSIC
|
||||
|
||||
config GPIO_BCM_KONA
|
||||
bool "Broadcom Kona GPIO"
|
||||
depends on OF_GPIO
|
||||
depends on OF_GPIO && (ARCH_BCM_MOBILE || COMPILE_TEST)
|
||||
help
|
||||
Turn on GPIO support for Broadcom "Kona" chips.
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o
|
||||
obj-$(CONFIG_GPIO_WM831X) += gpio-wm831x.o
|
||||
obj-$(CONFIG_GPIO_WM8350) += gpio-wm8350.o
|
||||
obj-$(CONFIG_GPIO_WM8994) += gpio-wm8994.o
|
||||
obj-$(CONFIG_GPIO_XGENE) += gpio-xgene.o
|
||||
obj-$(CONFIG_GPIO_XILINX) += gpio-xilinx.o
|
||||
obj-$(CONFIG_GPIO_XTENSA) += gpio-xtensa.o
|
||||
obj-$(CONFIG_GPIO_ZEVIO) += gpio-zevio.o
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/seq_file.h>
|
||||
@@ -27,8 +26,6 @@ struct adnp {
|
||||
unsigned int reg_shift;
|
||||
|
||||
struct mutex i2c_lock;
|
||||
|
||||
struct irq_domain *domain;
|
||||
struct mutex irq_lock;
|
||||
|
||||
u8 *irq_enable;
|
||||
@@ -253,6 +250,7 @@ static void adnp_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
|
||||
static int adnp_gpio_setup(struct adnp *adnp, unsigned int num_gpios)
|
||||
{
|
||||
struct gpio_chip *chip = &adnp->gpio;
|
||||
int err;
|
||||
|
||||
adnp->reg_shift = get_count_order(num_gpios) - 3;
|
||||
|
||||
@@ -272,6 +270,10 @@ static int adnp_gpio_setup(struct adnp *adnp, unsigned int num_gpios)
|
||||
chip->of_node = chip->dev->of_node;
|
||||
chip->owner = THIS_MODULE;
|
||||
|
||||
err = gpiochip_add(chip);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -326,7 +328,8 @@ static irqreturn_t adnp_irq(int irq, void *data)
|
||||
|
||||
for_each_set_bit(bit, &pending, 8) {
|
||||
unsigned int child_irq;
|
||||
child_irq = irq_find_mapping(adnp->domain, base + bit);
|
||||
child_irq = irq_find_mapping(adnp->gpio.irqdomain,
|
||||
base + bit);
|
||||
handle_nested_irq(child_irq);
|
||||
}
|
||||
}
|
||||
@@ -334,35 +337,32 @@ static irqreturn_t adnp_irq(int irq, void *data)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int adnp_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
|
||||
static void adnp_irq_mask(struct irq_data *d)
|
||||
{
|
||||
struct adnp *adnp = to_adnp(chip);
|
||||
return irq_create_mapping(adnp->domain, offset);
|
||||
}
|
||||
|
||||
static void adnp_irq_mask(struct irq_data *data)
|
||||
{
|
||||
struct adnp *adnp = irq_data_get_irq_chip_data(data);
|
||||
unsigned int reg = data->hwirq >> adnp->reg_shift;
|
||||
unsigned int pos = data->hwirq & 7;
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct adnp *adnp = to_adnp(gc);
|
||||
unsigned int reg = d->hwirq >> adnp->reg_shift;
|
||||
unsigned int pos = d->hwirq & 7;
|
||||
|
||||
adnp->irq_enable[reg] &= ~BIT(pos);
|
||||
}
|
||||
|
||||
static void adnp_irq_unmask(struct irq_data *data)
|
||||
static void adnp_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
struct adnp *adnp = irq_data_get_irq_chip_data(data);
|
||||
unsigned int reg = data->hwirq >> adnp->reg_shift;
|
||||
unsigned int pos = data->hwirq & 7;
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct adnp *adnp = to_adnp(gc);
|
||||
unsigned int reg = d->hwirq >> adnp->reg_shift;
|
||||
unsigned int pos = d->hwirq & 7;
|
||||
|
||||
adnp->irq_enable[reg] |= BIT(pos);
|
||||
}
|
||||
|
||||
static int adnp_irq_set_type(struct irq_data *data, unsigned int type)
|
||||
static int adnp_irq_set_type(struct irq_data *d, unsigned int type)
|
||||
{
|
||||
struct adnp *adnp = irq_data_get_irq_chip_data(data);
|
||||
unsigned int reg = data->hwirq >> adnp->reg_shift;
|
||||
unsigned int pos = data->hwirq & 7;
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct adnp *adnp = to_adnp(gc);
|
||||
unsigned int reg = d->hwirq >> adnp->reg_shift;
|
||||
unsigned int pos = d->hwirq & 7;
|
||||
|
||||
if (type & IRQ_TYPE_EDGE_RISING)
|
||||
adnp->irq_rise[reg] |= BIT(pos);
|
||||
@@ -387,16 +387,18 @@ static int adnp_irq_set_type(struct irq_data *data, unsigned int type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void adnp_irq_bus_lock(struct irq_data *data)
|
||||
static void adnp_irq_bus_lock(struct irq_data *d)
|
||||
{
|
||||
struct adnp *adnp = irq_data_get_irq_chip_data(data);
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct adnp *adnp = to_adnp(gc);
|
||||
|
||||
mutex_lock(&adnp->irq_lock);
|
||||
}
|
||||
|
||||
static void adnp_irq_bus_unlock(struct irq_data *data)
|
||||
static void adnp_irq_bus_unlock(struct irq_data *d)
|
||||
{
|
||||
struct adnp *adnp = irq_data_get_irq_chip_data(data);
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct adnp *adnp = to_adnp(gc);
|
||||
unsigned int num_regs = 1 << adnp->reg_shift, i;
|
||||
|
||||
mutex_lock(&adnp->i2c_lock);
|
||||
@@ -408,26 +410,6 @@ static void adnp_irq_bus_unlock(struct irq_data *data)
|
||||
mutex_unlock(&adnp->irq_lock);
|
||||
}
|
||||
|
||||
static int adnp_irq_reqres(struct irq_data *data)
|
||||
{
|
||||
struct adnp *adnp = irq_data_get_irq_chip_data(data);
|
||||
|
||||
if (gpio_lock_as_irq(&adnp->gpio, data->hwirq)) {
|
||||
dev_err(adnp->gpio.dev,
|
||||
"unable to lock HW IRQ %lu for IRQ\n",
|
||||
data->hwirq);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void adnp_irq_relres(struct irq_data *data)
|
||||
{
|
||||
struct adnp *adnp = irq_data_get_irq_chip_data(data);
|
||||
|
||||
gpio_unlock_as_irq(&adnp->gpio, data->hwirq);
|
||||
}
|
||||
|
||||
static struct irq_chip adnp_irq_chip = {
|
||||
.name = "gpio-adnp",
|
||||
.irq_mask = adnp_irq_mask,
|
||||
@@ -435,29 +417,6 @@ static struct irq_chip adnp_irq_chip = {
|
||||
.irq_set_type = adnp_irq_set_type,
|
||||
.irq_bus_lock = adnp_irq_bus_lock,
|
||||
.irq_bus_sync_unlock = adnp_irq_bus_unlock,
|
||||
.irq_request_resources = adnp_irq_reqres,
|
||||
.irq_release_resources = adnp_irq_relres,
|
||||
};
|
||||
|
||||
static int adnp_irq_map(struct irq_domain *domain, unsigned int irq,
|
||||
irq_hw_number_t hwirq)
|
||||
{
|
||||
irq_set_chip_data(irq, domain->host_data);
|
||||
irq_set_chip(irq, &adnp_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 adnp_irq_domain_ops = {
|
||||
.map = adnp_irq_map,
|
||||
.xlate = irq_domain_xlate_twocell,
|
||||
};
|
||||
|
||||
static int adnp_irq_setup(struct adnp *adnp)
|
||||
@@ -503,35 +462,28 @@ static int adnp_irq_setup(struct adnp *adnp)
|
||||
adnp->irq_enable[i] = 0x00;
|
||||
}
|
||||
|
||||
adnp->domain = irq_domain_add_linear(chip->of_node, chip->ngpio,
|
||||
&adnp_irq_domain_ops, adnp);
|
||||
|
||||
err = request_threaded_irq(adnp->client->irq, NULL, adnp_irq,
|
||||
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
|
||||
dev_name(chip->dev), adnp);
|
||||
err = devm_request_threaded_irq(chip->dev, adnp->client->irq,
|
||||
NULL, adnp_irq,
|
||||
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
|
||||
dev_name(chip->dev), adnp);
|
||||
if (err != 0) {
|
||||
dev_err(chip->dev, "can't request IRQ#%d: %d\n",
|
||||
adnp->client->irq, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
chip->to_irq = adnp_gpio_to_irq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void adnp_irq_teardown(struct adnp *adnp)
|
||||
{
|
||||
unsigned int irq, i;
|
||||
|
||||
free_irq(adnp->client->irq, adnp);
|
||||
|
||||
for (i = 0; i < adnp->gpio.ngpio; i++) {
|
||||
irq = irq_find_mapping(adnp->domain, i);
|
||||
if (irq > 0)
|
||||
irq_dispose_mapping(irq);
|
||||
err = gpiochip_irqchip_add(chip,
|
||||
&adnp_irq_chip,
|
||||
0,
|
||||
handle_simple_irq,
|
||||
IRQ_TYPE_NONE);
|
||||
if (err) {
|
||||
dev_err(chip->dev,
|
||||
"could not connect irqchip to gpiochip\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
irq_domain_remove(adnp->domain);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adnp_i2c_probe(struct i2c_client *client,
|
||||
@@ -558,38 +510,25 @@ static int adnp_i2c_probe(struct i2c_client *client,
|
||||
adnp->client = client;
|
||||
|
||||
err = adnp_gpio_setup(adnp, num_gpios);
|
||||
if (err < 0)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (of_find_property(np, "interrupt-controller", NULL)) {
|
||||
err = adnp_irq_setup(adnp);
|
||||
if (err < 0)
|
||||
goto teardown;
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = gpiochip_add(&adnp->gpio);
|
||||
if (err < 0)
|
||||
goto teardown;
|
||||
|
||||
i2c_set_clientdata(client, adnp);
|
||||
|
||||
return 0;
|
||||
|
||||
teardown:
|
||||
if (of_find_property(np, "interrupt-controller", NULL))
|
||||
adnp_irq_teardown(adnp);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int adnp_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct adnp *adnp = i2c_get_clientdata(client);
|
||||
struct device_node *np = client->dev.of_node;
|
||||
|
||||
gpiochip_remove(&adnp->gpio);
|
||||
if (of_find_property(np, "interrupt-controller", NULL))
|
||||
adnp_irq_teardown(adnp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -496,7 +496,7 @@ static struct irq_chip bcm_gpio_irq_chip = {
|
||||
.irq_release_resources = bcm_kona_gpio_irq_relres,
|
||||
};
|
||||
|
||||
static struct __initconst of_device_id bcm_kona_gpio_of_match[] = {
|
||||
static struct of_device_id const bcm_kona_gpio_of_match[] = {
|
||||
{ .compatible = "brcm,kona-gpio" },
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <linux/mfd/intel_soc_pmic.h>
|
||||
|
||||
#define CRYSTALCOVE_GPIO_NUM 16
|
||||
#define CRYSTALCOVE_VGPIO_NUM 94
|
||||
|
||||
#define UPDATE_IRQ_TYPE BIT(0)
|
||||
#define UPDATE_IRQ_MASK BIT(1)
|
||||
@@ -130,6 +131,9 @@ static int crystalcove_gpio_dir_in(struct gpio_chip *chip, unsigned gpio)
|
||||
{
|
||||
struct crystalcove_gpio *cg = to_cg(chip);
|
||||
|
||||
if (gpio > CRYSTALCOVE_VGPIO_NUM)
|
||||
return 0;
|
||||
|
||||
return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT),
|
||||
CTLO_INPUT_SET);
|
||||
}
|
||||
@@ -139,6 +143,9 @@ static int crystalcove_gpio_dir_out(struct gpio_chip *chip, unsigned gpio,
|
||||
{
|
||||
struct crystalcove_gpio *cg = to_cg(chip);
|
||||
|
||||
if (gpio > CRYSTALCOVE_VGPIO_NUM)
|
||||
return 0;
|
||||
|
||||
return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT),
|
||||
CTLO_OUTPUT_SET | value);
|
||||
}
|
||||
@@ -149,6 +156,9 @@ static int crystalcove_gpio_get(struct gpio_chip *chip, unsigned gpio)
|
||||
int ret;
|
||||
unsigned int val;
|
||||
|
||||
if (gpio > CRYSTALCOVE_VGPIO_NUM)
|
||||
return 0;
|
||||
|
||||
ret = regmap_read(cg->regmap, to_reg(gpio, CTRL_IN), &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -161,6 +171,9 @@ static void crystalcove_gpio_set(struct gpio_chip *chip,
|
||||
{
|
||||
struct crystalcove_gpio *cg = to_cg(chip);
|
||||
|
||||
if (gpio > CRYSTALCOVE_VGPIO_NUM)
|
||||
return;
|
||||
|
||||
if (value)
|
||||
regmap_update_bits(cg->regmap, to_reg(gpio, CTRL_OUT), 1, 1);
|
||||
else
|
||||
@@ -256,7 +269,7 @@ static irqreturn_t crystalcove_gpio_irq_handler(int irq, void *data)
|
||||
|
||||
pending = p0 | p1 << 8;
|
||||
|
||||
for (gpio = 0; gpio < cg->chip.ngpio; gpio++) {
|
||||
for (gpio = 0; gpio < CRYSTALCOVE_GPIO_NUM; gpio++) {
|
||||
if (pending & BIT(gpio)) {
|
||||
virq = irq_find_mapping(cg->chip.irqdomain, gpio);
|
||||
generic_handle_irq(virq);
|
||||
@@ -273,7 +286,7 @@ static void crystalcove_gpio_dbg_show(struct seq_file *s,
|
||||
int gpio, offset;
|
||||
unsigned int ctlo, ctli, mirqs0, mirqsx, irq;
|
||||
|
||||
for (gpio = 0; gpio < cg->chip.ngpio; gpio++) {
|
||||
for (gpio = 0; gpio < CRYSTALCOVE_GPIO_NUM; gpio++) {
|
||||
regmap_read(cg->regmap, to_reg(gpio, CTRL_OUT), &ctlo);
|
||||
regmap_read(cg->regmap, to_reg(gpio, CTRL_IN), &ctli);
|
||||
regmap_read(cg->regmap, gpio < 8 ? MGPIO0IRQS0 : MGPIO1IRQS0,
|
||||
@@ -320,7 +333,7 @@ static int crystalcove_gpio_probe(struct platform_device *pdev)
|
||||
cg->chip.get = crystalcove_gpio_get;
|
||||
cg->chip.set = crystalcove_gpio_set;
|
||||
cg->chip.base = -1;
|
||||
cg->chip.ngpio = CRYSTALCOVE_GPIO_NUM;
|
||||
cg->chip.ngpio = CRYSTALCOVE_VGPIO_NUM;
|
||||
cg->chip.can_sleep = true;
|
||||
cg->chip.dev = dev;
|
||||
cg->chip.dbg_show = crystalcove_gpio_dbg_show;
|
||||
@@ -346,7 +359,7 @@ static int crystalcove_gpio_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
|
||||
out_remove_gpio:
|
||||
WARN_ON(gpiochip_remove(&cg->chip));
|
||||
gpiochip_remove(&cg->chip);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -354,14 +367,11 @@ static int crystalcove_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct crystalcove_gpio *cg = platform_get_drvdata(pdev);
|
||||
int irq = platform_get_irq(pdev, 0);
|
||||
int err;
|
||||
|
||||
err = gpiochip_remove(&cg->chip);
|
||||
|
||||
gpiochip_remove(&cg->chip);
|
||||
if (irq >= 0)
|
||||
free_irq(irq, cg);
|
||||
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver crystalcove_gpio_driver = {
|
||||
|
||||
@@ -201,7 +201,8 @@ EXPORT_SYMBOL_GPL(cs5535_gpio_setup_event);
|
||||
|
||||
static int chip_gpio_request(struct gpio_chip *c, unsigned offset)
|
||||
{
|
||||
struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c;
|
||||
struct cs5535_gpio_chip *chip =
|
||||
container_of(c, struct cs5535_gpio_chip, chip);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&chip->lock, flags);
|
||||
@@ -241,7 +242,8 @@ static void chip_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
|
||||
|
||||
static int chip_direction_input(struct gpio_chip *c, unsigned offset)
|
||||
{
|
||||
struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c;
|
||||
struct cs5535_gpio_chip *chip =
|
||||
container_of(c, struct cs5535_gpio_chip, chip);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&chip->lock, flags);
|
||||
@@ -254,7 +256,8 @@ static int chip_direction_input(struct gpio_chip *c, unsigned offset)
|
||||
|
||||
static int chip_direction_output(struct gpio_chip *c, unsigned offset, int val)
|
||||
{
|
||||
struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c;
|
||||
struct cs5535_gpio_chip *chip =
|
||||
container_of(c, struct cs5535_gpio_chip, chip);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&chip->lock, flags);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -265,29 +265,27 @@ static int ks8695_gpio_show(struct seq_file *s, void *unused)
|
||||
seq_printf(s, "EXT%i ", i);
|
||||
|
||||
switch ((ctrl & intmask[i]) >> (4 * i)) {
|
||||
case IOPC_TM_LOW:
|
||||
seq_printf(s, "(Low)"); break;
|
||||
case IOPC_TM_HIGH:
|
||||
seq_printf(s, "(High)"); break;
|
||||
case IOPC_TM_RISING:
|
||||
seq_printf(s, "(Rising)"); break;
|
||||
case IOPC_TM_FALLING:
|
||||
seq_printf(s, "(Falling)"); break;
|
||||
case IOPC_TM_EDGE:
|
||||
seq_printf(s, "(Edges)"); break;
|
||||
case IOPC_TM_LOW:
|
||||
seq_printf(s, "(Low)"); break;
|
||||
case IOPC_TM_HIGH:
|
||||
seq_printf(s, "(High)"); break;
|
||||
case IOPC_TM_RISING:
|
||||
seq_printf(s, "(Rising)"); break;
|
||||
case IOPC_TM_FALLING:
|
||||
seq_printf(s, "(Falling)"); break;
|
||||
case IOPC_TM_EDGE:
|
||||
seq_printf(s, "(Edges)"); break;
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
seq_printf(s, "GPIO\t");
|
||||
}
|
||||
else if (i <= KS8695_GPIO_5) {
|
||||
} else if (i <= KS8695_GPIO_5) {
|
||||
if (ctrl & enable[i])
|
||||
seq_printf(s, "TOUT%i\t", i - KS8695_GPIO_4);
|
||||
else
|
||||
seq_printf(s, "GPIO\t");
|
||||
}
|
||||
else
|
||||
} else {
|
||||
seq_printf(s, "GPIO\t");
|
||||
}
|
||||
|
||||
seq_printf(s, "\t");
|
||||
|
||||
|
||||
@@ -479,7 +479,7 @@ static int mcp23s08_irq_setup(struct mcp23s08 *mcp)
|
||||
|
||||
mutex_init(&mcp->irq_lock);
|
||||
|
||||
mcp->irq_domain = irq_domain_add_linear(chip->of_node, chip->ngpio,
|
||||
mcp->irq_domain = irq_domain_add_linear(chip->dev->of_node, chip->ngpio,
|
||||
&irq_domain_simple_ops, mcp);
|
||||
if (!mcp->irq_domain)
|
||||
return -ENODEV;
|
||||
@@ -581,7 +581,7 @@ done:
|
||||
|
||||
static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
|
||||
void *data, unsigned addr, unsigned type,
|
||||
unsigned base, unsigned pullups)
|
||||
struct mcp23s08_platform_data *pdata, int cs)
|
||||
{
|
||||
int status;
|
||||
bool mirror = false;
|
||||
@@ -635,7 +635,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mcp->chip.base = base;
|
||||
mcp->chip.base = pdata->base;
|
||||
mcp->chip.can_sleep = true;
|
||||
mcp->chip.dev = dev;
|
||||
mcp->chip.owner = THIS_MODULE;
|
||||
@@ -648,11 +648,9 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
|
||||
if (status < 0)
|
||||
goto fail;
|
||||
|
||||
mcp->irq_controller = of_property_read_bool(mcp->chip.of_node,
|
||||
"interrupt-controller");
|
||||
mcp->irq_controller = pdata->irq_controller;
|
||||
if (mcp->irq && mcp->irq_controller && (type == MCP_TYPE_017))
|
||||
mirror = of_property_read_bool(mcp->chip.of_node,
|
||||
"microchip,irq-mirror");
|
||||
mirror = pdata->mirror;
|
||||
|
||||
if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN) || mirror) {
|
||||
/* mcp23s17 has IOCON twice, make sure they are in sync */
|
||||
@@ -668,7 +666,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
|
||||
}
|
||||
|
||||
/* configure ~100K pullups */
|
||||
status = mcp->ops->write(mcp, MCP_GPPU, pullups);
|
||||
status = mcp->ops->write(mcp, MCP_GPPU, pdata->chip[cs].pullups);
|
||||
if (status < 0)
|
||||
goto fail;
|
||||
|
||||
@@ -768,25 +766,29 @@ MODULE_DEVICE_TABLE(of, mcp23s08_i2c_of_match);
|
||||
static int mcp230xx_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct mcp23s08_platform_data *pdata;
|
||||
struct mcp23s08_platform_data *pdata, local_pdata;
|
||||
struct mcp23s08 *mcp;
|
||||
int status, base, pullups;
|
||||
int status;
|
||||
const struct of_device_id *match;
|
||||
|
||||
match = of_match_device(of_match_ptr(mcp23s08_i2c_of_match),
|
||||
&client->dev);
|
||||
pdata = dev_get_platdata(&client->dev);
|
||||
if (match || !pdata) {
|
||||
base = -1;
|
||||
pullups = 0;
|
||||
if (match) {
|
||||
pdata = &local_pdata;
|
||||
pdata->base = -1;
|
||||
pdata->chip[0].pullups = 0;
|
||||
pdata->irq_controller = of_property_read_bool(
|
||||
client->dev.of_node,
|
||||
"interrupt-controller");
|
||||
pdata->mirror = of_property_read_bool(client->dev.of_node,
|
||||
"microchip,irq-mirror");
|
||||
client->irq = irq_of_parse_and_map(client->dev.of_node, 0);
|
||||
} else {
|
||||
if (!gpio_is_valid(pdata->base)) {
|
||||
pdata = dev_get_platdata(&client->dev);
|
||||
if (!pdata || !gpio_is_valid(pdata->base)) {
|
||||
dev_dbg(&client->dev, "invalid platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
base = pdata->base;
|
||||
pullups = pdata->chip[0].pullups;
|
||||
}
|
||||
|
||||
mcp = kzalloc(sizeof(*mcp), GFP_KERNEL);
|
||||
@@ -795,7 +797,7 @@ static int mcp230xx_probe(struct i2c_client *client,
|
||||
|
||||
mcp->irq = client->irq;
|
||||
status = mcp23s08_probe_one(mcp, &client->dev, client, client->addr,
|
||||
id->driver_data, base, pullups);
|
||||
id->driver_data, pdata, 0);
|
||||
if (status)
|
||||
goto fail;
|
||||
|
||||
@@ -863,14 +865,12 @@ static void mcp23s08_i2c_exit(void) { }
|
||||
|
||||
static int mcp23s08_probe(struct spi_device *spi)
|
||||
{
|
||||
struct mcp23s08_platform_data *pdata;
|
||||
struct mcp23s08_platform_data *pdata, local_pdata;
|
||||
unsigned addr;
|
||||
int chips = 0;
|
||||
struct mcp23s08_driver_data *data;
|
||||
int status, type;
|
||||
unsigned base = -1,
|
||||
ngpio = 0,
|
||||
pullups[ARRAY_SIZE(pdata->chip)];
|
||||
unsigned ngpio = 0;
|
||||
const struct of_device_id *match;
|
||||
u32 spi_present_mask = 0;
|
||||
|
||||
@@ -893,11 +893,18 @@ static int mcp23s08_probe(struct spi_device *spi)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pdata = &local_pdata;
|
||||
pdata->base = -1;
|
||||
for (addr = 0; addr < ARRAY_SIZE(pdata->chip); addr++) {
|
||||
pullups[addr] = 0;
|
||||
pdata->chip[addr].pullups = 0;
|
||||
if (spi_present_mask & (1 << addr))
|
||||
chips++;
|
||||
}
|
||||
pdata->irq_controller = of_property_read_bool(
|
||||
spi->dev.of_node,
|
||||
"interrupt-controller");
|
||||
pdata->mirror = of_property_read_bool(spi->dev.of_node,
|
||||
"microchip,irq-mirror");
|
||||
} else {
|
||||
type = spi_get_device_id(spi)->driver_data;
|
||||
pdata = dev_get_platdata(&spi->dev);
|
||||
@@ -917,10 +924,7 @@ static int mcp23s08_probe(struct spi_device *spi)
|
||||
return -EINVAL;
|
||||
}
|
||||
spi_present_mask |= 1 << addr;
|
||||
pullups[addr] = pdata->chip[addr].pullups;
|
||||
}
|
||||
|
||||
base = pdata->base;
|
||||
}
|
||||
|
||||
if (!chips)
|
||||
@@ -938,13 +942,13 @@ static int mcp23s08_probe(struct spi_device *spi)
|
||||
chips--;
|
||||
data->mcp[addr] = &data->chip[chips];
|
||||
status = mcp23s08_probe_one(data->mcp[addr], &spi->dev, spi,
|
||||
0x40 | (addr << 1), type, base,
|
||||
pullups[addr]);
|
||||
0x40 | (addr << 1), type, pdata,
|
||||
addr);
|
||||
if (status < 0)
|
||||
goto fail;
|
||||
|
||||
if (base != -1)
|
||||
base += (type == MCP_TYPE_S17) ? 16 : 8;
|
||||
if (pdata->base != -1)
|
||||
pdata->base += (type == MCP_TYPE_S17) ? 16 : 8;
|
||||
ngpio += (type == MCP_TYPE_S17) ? 16 : 8;
|
||||
}
|
||||
data->ngpio = ngpio;
|
||||
|
||||
@@ -857,16 +857,6 @@ static void omap_gpio_unmask_irq(struct irq_data *d)
|
||||
spin_unlock_irqrestore(&bank->lock, flags);
|
||||
}
|
||||
|
||||
static struct irq_chip gpio_irq_chip = {
|
||||
.name = "GPIO",
|
||||
.irq_shutdown = omap_gpio_irq_shutdown,
|
||||
.irq_ack = omap_gpio_ack_irq,
|
||||
.irq_mask = omap_gpio_mask_irq,
|
||||
.irq_unmask = omap_gpio_unmask_irq,
|
||||
.irq_set_type = omap_gpio_irq_type,
|
||||
.irq_set_wake = omap_gpio_wake_enable,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
static int omap_mpuio_suspend_noirq(struct device *dev)
|
||||
@@ -1088,7 +1078,7 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start,
|
||||
IRQ_NOREQUEST | IRQ_NOPROBE, 0);
|
||||
}
|
||||
|
||||
static int omap_gpio_chip_init(struct gpio_bank *bank)
|
||||
static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
|
||||
{
|
||||
int j;
|
||||
static int gpio;
|
||||
@@ -1137,17 +1127,17 @@ static int omap_gpio_chip_init(struct gpio_bank *bank)
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = gpiochip_irqchip_add(&bank->chip, &gpio_irq_chip,
|
||||
ret = gpiochip_irqchip_add(&bank->chip, irqc,
|
||||
irq_base, omap_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);
|
||||
gpiochip_remove(&bank->chip);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
gpiochip_set_chained_irqchip(&bank->chip, &gpio_irq_chip,
|
||||
gpiochip_set_chained_irqchip(&bank->chip, irqc,
|
||||
bank->irq, omap_gpio_irq_handler);
|
||||
|
||||
for (j = 0; j < bank->width; j++) {
|
||||
@@ -1172,6 +1162,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
|
||||
const struct omap_gpio_platform_data *pdata;
|
||||
struct resource *res;
|
||||
struct gpio_bank *bank;
|
||||
struct irq_chip *irqc;
|
||||
int ret;
|
||||
|
||||
match = of_match_device(of_match_ptr(omap_gpio_match), dev);
|
||||
@@ -1186,6 +1177,18 @@ static int omap_gpio_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
irqc = devm_kzalloc(dev, sizeof(*irqc), GFP_KERNEL);
|
||||
if (!irqc)
|
||||
return -ENOMEM;
|
||||
|
||||
irqc->irq_shutdown = omap_gpio_irq_shutdown,
|
||||
irqc->irq_ack = omap_gpio_ack_irq,
|
||||
irqc->irq_mask = omap_gpio_mask_irq,
|
||||
irqc->irq_unmask = omap_gpio_unmask_irq,
|
||||
irqc->irq_set_type = omap_gpio_irq_type,
|
||||
irqc->irq_set_wake = omap_gpio_wake_enable,
|
||||
irqc->name = dev_name(&pdev->dev);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (unlikely(!res)) {
|
||||
dev_err(dev, "Invalid IRQ resource\n");
|
||||
@@ -1241,7 +1244,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
|
||||
|
||||
omap_gpio_mod_init(bank);
|
||||
|
||||
ret = omap_gpio_chip_init(bank);
|
||||
ret = omap_gpio_chip_init(bank, irqc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user