Commit aa284d64 authored by Linus Walleij's avatar Linus Walleij

Merge tag 'gpio-5.0-rc4-fixes-for-linus' of...

Merge tag 'gpio-5.0-rc4-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux into fixes

GPIO fixes for 5.0-rc4

- fix from Roger Quadros for a warning resulting from reusing the same
  irqchip for multiple pcf857x instances
- fix for missing line event timestamp when using nested interrupts
- two fixes for the sprd driver dealing with value reading and
  the irq chip
- fix for the direction_output callback for altera-a10sr
parents 49a57857 2095a45e
...@@ -66,8 +66,10 @@ static int altr_a10sr_gpio_direction_input(struct gpio_chip *gc, ...@@ -66,8 +66,10 @@ static int altr_a10sr_gpio_direction_input(struct gpio_chip *gc,
static int altr_a10sr_gpio_direction_output(struct gpio_chip *gc, static int altr_a10sr_gpio_direction_output(struct gpio_chip *gc,
unsigned int nr, int value) unsigned int nr, int value)
{ {
if (nr <= (ALTR_A10SR_OUT_VALID_RANGE_HI - ALTR_A10SR_LED_VALID_SHIFT)) if (nr <= (ALTR_A10SR_OUT_VALID_RANGE_HI - ALTR_A10SR_LED_VALID_SHIFT)) {
altr_a10sr_gpio_set(gc, nr, value);
return 0; return 0;
}
return -EINVAL; return -EINVAL;
} }
......
...@@ -180,7 +180,18 @@ static void sprd_eic_free(struct gpio_chip *chip, unsigned int offset) ...@@ -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) 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) 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) ...@@ -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); irq_set_handler_locked(data, handle_edge_irq);
break; break;
case IRQ_TYPE_EDGE_BOTH: 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); sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 1);
irq_set_handler_locked(data, handle_edge_irq); irq_set_handler_locked(data, handle_edge_irq);
break; break;
......
...@@ -84,6 +84,7 @@ MODULE_DEVICE_TABLE(of, pcf857x_of_table); ...@@ -84,6 +84,7 @@ MODULE_DEVICE_TABLE(of, pcf857x_of_table);
*/ */
struct pcf857x { struct pcf857x {
struct gpio_chip chip; struct gpio_chip chip;
struct irq_chip irqchip;
struct i2c_client *client; struct i2c_client *client;
struct mutex lock; /* protect 'out' */ struct mutex lock; /* protect 'out' */
unsigned out; /* software latch */ unsigned out; /* software latch */
...@@ -252,18 +253,6 @@ static void pcf857x_irq_bus_sync_unlock(struct irq_data *data) ...@@ -252,18 +253,6 @@ static void pcf857x_irq_bus_sync_unlock(struct irq_data *data)
mutex_unlock(&gpio->lock); 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, static int pcf857x_probe(struct i2c_client *client,
...@@ -376,8 +365,17 @@ static int pcf857x_probe(struct i2c_client *client, ...@@ -376,8 +365,17 @@ static int pcf857x_probe(struct i2c_client *client,
/* Enable irqchip if we have an interrupt */ /* Enable irqchip if we have an interrupt */
if (client->irq) { 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, status = gpiochip_irqchip_add_nested(&gpio->chip,
&pcf857x_irq_chip, &gpio->irqchip,
0, handle_level_irq, 0, handle_level_irq,
IRQ_TYPE_NONE); IRQ_TYPE_NONE);
if (status) { if (status) {
...@@ -392,7 +390,7 @@ static int pcf857x_probe(struct i2c_client *client, ...@@ -392,7 +390,7 @@ static int pcf857x_probe(struct i2c_client *client,
if (status) if (status)
goto fail; goto fail;
gpiochip_set_nested_irqchip(&gpio->chip, &pcf857x_irq_chip, gpiochip_set_nested_irqchip(&gpio->chip, &gpio->irqchip,
client->irq); client->irq);
gpio->irq_parent = client->irq; gpio->irq_parent = client->irq;
} }
......
...@@ -828,7 +828,14 @@ static irqreturn_t lineevent_irq_thread(int irq, void *p) ...@@ -828,7 +828,14 @@ static irqreturn_t lineevent_irq_thread(int irq, void *p)
/* Do not leak kernel stack to userspace */ /* Do not leak kernel stack to userspace */
memset(&ge, 0, sizeof(ge)); 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 if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE
&& le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) { && le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment