aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2019-02-17 21:59:33 +0100
committerLinus Walleij <linus.walleij@linaro.org>2019-02-17 21:59:33 +0100
commit8fab3d713ca36bf4ad4dadec0bf38f5e70b8999d (patch)
tree18cdadced0870584ceffa02eed47f4c86da8263c /drivers/gpio
parentspmi: pmic-arb: select IRQ_DOMAIN_HIERARCHY in Kconfig (diff)
parentgpio: altera-a10sr: Trivial coding style fix (diff)
downloadlinux-dev-8fab3d713ca36bf4ad4dadec0bf38f5e70b8999d.tar.xz
linux-dev-8fab3d713ca36bf4ad4dadec0bf38f5e70b8999d.zip
Merge tag 'gpio-v5.1-updates-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux into devel
gpio updates for v5.1 - support for a new variant of pca953x - documentation fix from Wolfram - some tegra186 name changes - two minor fixes for madera and altera-a10sr
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-altera-a10sr.c15
-rw-r--r--drivers/gpio/gpio-eic-sprd.c14
-rw-r--r--drivers/gpio/gpio-madera.c2
-rw-r--r--drivers/gpio/gpio-pca953x.c3
-rw-r--r--drivers/gpio/gpio-pcf857x.c26
-rw-r--r--drivers/gpio/gpio-tegra186.c70
-rw-r--r--drivers/gpio/gpio-vf610.c5
-rw-r--r--drivers/gpio/gpiolib-acpi.c7
-rw-r--r--drivers/gpio/gpiolib.c9
9 files changed, 86 insertions, 65 deletions
diff --git a/drivers/gpio/gpio-altera-a10sr.c b/drivers/gpio/gpio-altera-a10sr.c
index 6b11f1314248..1cea4efccf7c 100644
--- a/drivers/gpio/gpio-altera-a10sr.c
+++ b/drivers/gpio/gpio-altera-a10sr.c
@@ -58,17 +58,20 @@ static void altr_a10sr_gpio_set(struct gpio_chip *chip, unsigned int offset,
static int altr_a10sr_gpio_direction_input(struct gpio_chip *gc,
unsigned int nr)
{
- if (nr >= (ALTR_A10SR_IN_VALID_RANGE_LO - ALTR_A10SR_LED_VALID_SHIFT))
- return 0;
- return -EINVAL;
+ if (nr < (ALTR_A10SR_IN_VALID_RANGE_LO - ALTR_A10SR_LED_VALID_SHIFT))
+ return -EINVAL;
+
+ return 0;
}
static int altr_a10sr_gpio_direction_output(struct gpio_chip *gc,
unsigned int nr, int value)
{
- if (nr <= (ALTR_A10SR_OUT_VALID_RANGE_HI - ALTR_A10SR_LED_VALID_SHIFT))
- return 0;
- return -EINVAL;
+ if (nr > (ALTR_A10SR_OUT_VALID_RANGE_HI - ALTR_A10SR_LED_VALID_SHIFT))
+ return -EINVAL;
+
+ altr_a10sr_gpio_set(gc, nr, value);
+ return 0;
}
static const struct gpio_chip altr_a10sr_gc = {
diff --git a/drivers/gpio/gpio-eic-sprd.c b/drivers/gpio/gpio-eic-sprd.c
index 64cc87d91790..f0223cee9774 100644
--- a/drivers/gpio/gpio-eic-sprd.c
+++ b/drivers/gpio/gpio-eic-sprd.c
@@ -180,7 +180,18 @@ static void sprd_eic_free(struct gpio_chip *chip, unsigned int offset)
static int sprd_eic_get(struct gpio_chip *chip, unsigned int offset)
{
- return sprd_eic_read(chip, offset, SPRD_EIC_DBNC_DATA);
+ struct sprd_eic *sprd_eic = gpiochip_get_data(chip);
+
+ switch (sprd_eic->type) {
+ case SPRD_EIC_DEBOUNCE:
+ return sprd_eic_read(chip, offset, SPRD_EIC_DBNC_DATA);
+ case SPRD_EIC_ASYNC:
+ return sprd_eic_read(chip, offset, SPRD_EIC_ASYNC_DATA);
+ case SPRD_EIC_SYNC:
+ return sprd_eic_read(chip, offset, SPRD_EIC_SYNC_DATA);
+ default:
+ return -ENOTSUPP;
+ }
}
static int sprd_eic_direction_input(struct gpio_chip *chip, unsigned int offset)
@@ -368,6 +379,7 @@ static int sprd_eic_irq_set_type(struct irq_data *data, unsigned int flow_type)
irq_set_handler_locked(data, handle_edge_irq);
break;
case IRQ_TYPE_EDGE_BOTH:
+ sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0);
sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 1);
irq_set_handler_locked(data, handle_edge_irq);
break;
diff --git a/drivers/gpio/gpio-madera.c b/drivers/gpio/gpio-madera.c
index 7ba68d1a0932..c9dad0543672 100644
--- a/drivers/gpio/gpio-madera.c
+++ b/drivers/gpio/gpio-madera.c
@@ -107,7 +107,7 @@ static void madera_gpio_set(struct gpio_chip *chip, unsigned int offset,
MADERA_GPIO1_CTRL_1 + reg_offset, ret);
}
-static struct gpio_chip madera_gpio_chip = {
+static const struct gpio_chip madera_gpio_chip = {
.label = "madera",
.owner = THIS_MODULE,
.request = gpiochip_generic_request,
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index 1e5579acd275..cf50d7dbf6ff 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -88,6 +88,7 @@ static const struct i2c_device_id pca953x_id[] = {
{ "pca9575", 16 | PCA957X_TYPE | PCA_INT, },
{ "pca9698", 40 | PCA953X_TYPE, },
+ { "pcal6416", 16 | PCA953X_TYPE | PCA_INT | PCA_PCAL, },
{ "pcal6524", 24 | PCA953X_TYPE | PCA_INT | PCA_PCAL, },
{ "pcal9555a", 16 | PCA953X_TYPE | PCA_INT | PCA_PCAL, },
@@ -296,7 +297,7 @@ static bool pca953x_volatile_register(struct device *dev, unsigned int reg)
return pca953x_check_register(chip, reg, bank);
}
-const struct regmap_config pca953x_i2c_regmap = {
+static const struct regmap_config pca953x_i2c_regmap = {
.reg_bits = 8,
.val_bits = 8,
diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c
index 064c1d0a93e0..c9b650f617fa 100644
--- a/drivers/gpio/gpio-pcf857x.c
+++ b/drivers/gpio/gpio-pcf857x.c
@@ -84,6 +84,7 @@ MODULE_DEVICE_TABLE(of, pcf857x_of_table);
*/
struct pcf857x {
struct gpio_chip chip;
+ struct irq_chip irqchip;
struct i2c_client *client;
struct mutex lock; /* protect 'out' */
unsigned out; /* software latch */
@@ -240,18 +241,6 @@ static void pcf857x_irq_bus_sync_unlock(struct irq_data *data)
mutex_unlock(&gpio->lock);
}
-static struct irq_chip pcf857x_irq_chip = {
- .name = "pcf857x",
- .irq_enable = pcf857x_irq_enable,
- .irq_disable = pcf857x_irq_disable,
- .irq_ack = noop,
- .irq_mask = noop,
- .irq_unmask = noop,
- .irq_set_wake = pcf857x_irq_set_wake,
- .irq_bus_lock = pcf857x_irq_bus_lock,
- .irq_bus_sync_unlock = pcf857x_irq_bus_sync_unlock,
-};
-
/*-------------------------------------------------------------------------*/
static int pcf857x_probe(struct i2c_client *client,
@@ -364,8 +353,17 @@ static int pcf857x_probe(struct i2c_client *client,
/* Enable irqchip if we have an interrupt */
if (client->irq) {
+ gpio->irqchip.name = "pcf857x",
+ gpio->irqchip.irq_enable = pcf857x_irq_enable,
+ gpio->irqchip.irq_disable = pcf857x_irq_disable,
+ gpio->irqchip.irq_ack = noop,
+ gpio->irqchip.irq_mask = noop,
+ gpio->irqchip.irq_unmask = noop,
+ gpio->irqchip.irq_set_wake = pcf857x_irq_set_wake,
+ gpio->irqchip.irq_bus_lock = pcf857x_irq_bus_lock,
+ gpio->irqchip.irq_bus_sync_unlock = pcf857x_irq_bus_sync_unlock,
status = gpiochip_irqchip_add_nested(&gpio->chip,
- &pcf857x_irq_chip,
+ &gpio->irqchip,
0, handle_level_irq,
IRQ_TYPE_NONE);
if (status) {
@@ -380,7 +378,7 @@ static int pcf857x_probe(struct i2c_client *client,
if (status)
goto fail;
- gpiochip_set_nested_irqchip(&gpio->chip, &pcf857x_irq_chip,
+ gpiochip_set_nested_irqchip(&gpio->chip, &gpio->irqchip,
client->irq);
}
diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c
index 66ec38bb7954..7d42e3d7572c 100644
--- a/drivers/gpio/gpio-tegra186.c
+++ b/drivers/gpio/gpio-tegra186.c
@@ -529,8 +529,8 @@ static int tegra186_gpio_remove(struct platform_device *pdev)
return 0;
}
-#define TEGRA_MAIN_GPIO_PORT(port, base, count, controller) \
- [TEGRA_MAIN_GPIO_PORT_##port] = { \
+#define TEGRA186_MAIN_GPIO_PORT(port, base, count, controller) \
+ [TEGRA186_MAIN_GPIO_PORT_##port] = { \
.name = #port, \
.offset = base, \
.pins = count, \
@@ -538,29 +538,29 @@ static int tegra186_gpio_remove(struct platform_device *pdev)
}
static const struct tegra_gpio_port tegra186_main_ports[] = {
- TEGRA_MAIN_GPIO_PORT( A, 0x2000, 7, 2),
- TEGRA_MAIN_GPIO_PORT( B, 0x3000, 7, 3),
- TEGRA_MAIN_GPIO_PORT( C, 0x3200, 7, 3),
- TEGRA_MAIN_GPIO_PORT( D, 0x3400, 6, 3),
- TEGRA_MAIN_GPIO_PORT( E, 0x2200, 8, 2),
- TEGRA_MAIN_GPIO_PORT( F, 0x2400, 6, 2),
- TEGRA_MAIN_GPIO_PORT( G, 0x4200, 6, 4),
- TEGRA_MAIN_GPIO_PORT( H, 0x1000, 7, 1),
- TEGRA_MAIN_GPIO_PORT( I, 0x0800, 8, 0),
- TEGRA_MAIN_GPIO_PORT( J, 0x5000, 8, 5),
- TEGRA_MAIN_GPIO_PORT( K, 0x5200, 1, 5),
- TEGRA_MAIN_GPIO_PORT( L, 0x1200, 8, 1),
- TEGRA_MAIN_GPIO_PORT( M, 0x5600, 6, 5),
- TEGRA_MAIN_GPIO_PORT( N, 0x0000, 7, 0),
- TEGRA_MAIN_GPIO_PORT( O, 0x0200, 4, 0),
- TEGRA_MAIN_GPIO_PORT( P, 0x4000, 7, 4),
- TEGRA_MAIN_GPIO_PORT( Q, 0x0400, 6, 0),
- TEGRA_MAIN_GPIO_PORT( R, 0x0a00, 6, 0),
- TEGRA_MAIN_GPIO_PORT( T, 0x0600, 4, 0),
- TEGRA_MAIN_GPIO_PORT( X, 0x1400, 8, 1),
- TEGRA_MAIN_GPIO_PORT( Y, 0x1600, 7, 1),
- TEGRA_MAIN_GPIO_PORT(BB, 0x2600, 2, 2),
- TEGRA_MAIN_GPIO_PORT(CC, 0x5400, 4, 5),
+ TEGRA186_MAIN_GPIO_PORT( A, 0x2000, 7, 2),
+ TEGRA186_MAIN_GPIO_PORT( B, 0x3000, 7, 3),
+ TEGRA186_MAIN_GPIO_PORT( C, 0x3200, 7, 3),
+ TEGRA186_MAIN_GPIO_PORT( D, 0x3400, 6, 3),
+ TEGRA186_MAIN_GPIO_PORT( E, 0x2200, 8, 2),
+ TEGRA186_MAIN_GPIO_PORT( F, 0x2400, 6, 2),
+ TEGRA186_MAIN_GPIO_PORT( G, 0x4200, 6, 4),
+ TEGRA186_MAIN_GPIO_PORT( H, 0x1000, 7, 1),
+ TEGRA186_MAIN_GPIO_PORT( I, 0x0800, 8, 0),
+ TEGRA186_MAIN_GPIO_PORT( J, 0x5000, 8, 5),
+ TEGRA186_MAIN_GPIO_PORT( K, 0x5200, 1, 5),
+ TEGRA186_MAIN_GPIO_PORT( L, 0x1200, 8, 1),
+ TEGRA186_MAIN_GPIO_PORT( M, 0x5600, 6, 5),
+ TEGRA186_MAIN_GPIO_PORT( N, 0x0000, 7, 0),
+ TEGRA186_MAIN_GPIO_PORT( O, 0x0200, 4, 0),
+ TEGRA186_MAIN_GPIO_PORT( P, 0x4000, 7, 4),
+ TEGRA186_MAIN_GPIO_PORT( Q, 0x0400, 6, 0),
+ TEGRA186_MAIN_GPIO_PORT( R, 0x0a00, 6, 0),
+ TEGRA186_MAIN_GPIO_PORT( T, 0x0600, 4, 0),
+ TEGRA186_MAIN_GPIO_PORT( X, 0x1400, 8, 1),
+ TEGRA186_MAIN_GPIO_PORT( Y, 0x1600, 7, 1),
+ TEGRA186_MAIN_GPIO_PORT(BB, 0x2600, 2, 2),
+ TEGRA186_MAIN_GPIO_PORT(CC, 0x5400, 4, 5),
};
static const struct tegra_gpio_soc tegra186_main_soc = {
@@ -569,8 +569,8 @@ static const struct tegra_gpio_soc tegra186_main_soc = {
.name = "tegra186-gpio",
};
-#define TEGRA_AON_GPIO_PORT(port, base, count, controller) \
- [TEGRA_AON_GPIO_PORT_##port] = { \
+#define TEGRA186_AON_GPIO_PORT(port, base, count, controller) \
+ [TEGRA186_AON_GPIO_PORT_##port] = { \
.name = #port, \
.offset = base, \
.pins = count, \
@@ -578,14 +578,14 @@ static const struct tegra_gpio_soc tegra186_main_soc = {
}
static const struct tegra_gpio_port tegra186_aon_ports[] = {
- TEGRA_AON_GPIO_PORT( S, 0x0200, 5, 0),
- TEGRA_AON_GPIO_PORT( U, 0x0400, 6, 0),
- TEGRA_AON_GPIO_PORT( V, 0x0800, 8, 0),
- TEGRA_AON_GPIO_PORT( W, 0x0a00, 8, 0),
- TEGRA_AON_GPIO_PORT( Z, 0x0e00, 4, 0),
- TEGRA_AON_GPIO_PORT(AA, 0x0c00, 8, 0),
- TEGRA_AON_GPIO_PORT(EE, 0x0600, 3, 0),
- TEGRA_AON_GPIO_PORT(FF, 0x0000, 5, 0),
+ TEGRA186_AON_GPIO_PORT( S, 0x0200, 5, 0),
+ TEGRA186_AON_GPIO_PORT( U, 0x0400, 6, 0),
+ TEGRA186_AON_GPIO_PORT( V, 0x0800, 8, 0),
+ TEGRA186_AON_GPIO_PORT( W, 0x0a00, 8, 0),
+ TEGRA186_AON_GPIO_PORT( Z, 0x0e00, 4, 0),
+ TEGRA186_AON_GPIO_PORT(AA, 0x0c00, 8, 0),
+ TEGRA186_AON_GPIO_PORT(EE, 0x0600, 3, 0),
+ TEGRA186_AON_GPIO_PORT(FF, 0x0000, 5, 0),
};
static const struct tegra_gpio_soc tegra186_aon_soc = {
diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c
index 1b79ebcfce3e..541fa6ac399d 100644
--- a/drivers/gpio/gpio-vf610.c
+++ b/drivers/gpio/gpio-vf610.c
@@ -253,6 +253,7 @@ static int vf610_gpio_probe(struct platform_device *pdev)
struct vf610_gpio_port *port;
struct resource *iores;
struct gpio_chip *gc;
+ int i;
int ret;
port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
@@ -319,6 +320,10 @@ static int vf610_gpio_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
+ /* Mask all GPIO interrupts */
+ for (i = 0; i < gc->ngpio; i++)
+ vf610_gpio_writel(0, port->base + PORT_PCR(i));
+
/* Clear the interrupt status register for all GPIO's */
vf610_gpio_writel(~0, port->base + PORT_ISFR);
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index 3401823427f6..15077c0797b9 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -357,8 +357,6 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip)
mutex_unlock(&acpi_gpio_deferred_req_irqs_lock);
list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) {
- struct gpio_desc *desc;
-
if (event->irq_requested) {
if (event->irq_is_wake)
disable_irq_wake(event->irq);
@@ -366,11 +364,8 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip)
free_irq(event->irq, event);
}
- desc = event->desc;
- if (WARN_ON(IS_ERR(desc)))
- continue;
gpiochip_unlock_as_irq(chip, event->pin);
- gpiochip_free_own_desc(desc);
+ gpiochip_free_own_desc(event->desc);
list_del(&event->node);
kfree(event);
}
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 9be4c9401172..144af0733581 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -828,7 +828,14 @@ static irqreturn_t lineevent_irq_thread(int irq, void *p)
/* Do not leak kernel stack to userspace */
memset(&ge, 0, sizeof(ge));
- ge.timestamp = le->timestamp;
+ /*
+ * We may be running from a nested threaded interrupt in which case
+ * we didn't get the timestamp from lineevent_irq_handler().
+ */
+ if (!le->timestamp)
+ ge.timestamp = ktime_get_real_ns();
+ else
+ ge.timestamp = le->timestamp;
if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE
&& le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) {