Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aa284d64 authored by Linus Walleij's avatar Linus Walleij
Browse files

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
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -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,
					    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 -EINVAL;
}

+13 −1
Original line number Diff line number Diff line
@@ -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)
{
	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;
+12 −14
Original line number Diff line number Diff line
@@ -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 */
@@ -252,18 +253,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,
@@ -376,8 +365,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) {
@@ -392,7 +390,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);
		gpio->irq_parent = client->irq;
	}
+8 −1
Original line number Diff line number Diff line
@@ -828,6 +828,13 @@ static irqreturn_t lineevent_irq_thread(int irq, void *p)
	/* Do not leak kernel stack to userspace */
	memset(&ge, 0, sizeof(ge));

	/*
	 * 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