Commit bc380733 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull GPIO fixes from Linus Walleij:
 "Hopefully last round of GPIO fixes.

  The ACPI patch is pretty important for some laptop users, the rest is
  driver-specific for embedded (mostly ARM) systems.

  I took out one ACPI patch that wasn't critical enough because I
  couldn't justify sending it at this point, and that is why the commit
  date is today, but the patches have been in linux-next.

  Sorry for not sending some of them earlier :(

  Notice that we have a co-maintainer for GPIO now, Bartosz Golaszewski,
  and he might jump in and make some pull requests at times when I am
  off.

  Summary:

   - ACPI IRQ request deferral

   - OMAP: revert deferred wakeup quirk

   - MAX7301: fix DMA safe memory handling

   - MVEBU: selective probe failure on missing clk"

* tag 'gpio-v4.20-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio:
  gpio: mvebu: only fail on missing clk if pwm is actually to be used
  gpio: max7301: fix driver for use with CONFIG_VMAP_STACK
  gpio: gpio-omap: Revert deferred wakeup quirk handling for regressions
  gpiolib-acpi: Only defer request_irq for GpioInt ACPI event handlers
parents 78361955 c8da642d
Loading
Loading
Loading
Loading
+3 −9
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ static int max7301_spi_write(struct device *dev, unsigned int reg,
	struct spi_device *spi = to_spi_device(dev);
	u16 word = ((reg & 0x7F) << 8) | (val & 0xFF);

	return spi_write(spi, (const u8 *)&word, sizeof(word));
	return spi_write_then_read(spi, &word, sizeof(word), NULL, 0);
}

/* A read from the MAX7301 means two transfers; here, one message each */
@@ -37,14 +37,8 @@ static int max7301_spi_read(struct device *dev, unsigned int reg)
	struct spi_device *spi = to_spi_device(dev);

	word = 0x8000 | (reg << 8);
	ret = spi_write(spi, (const u8 *)&word, sizeof(word));
	if (ret)
		return ret;
	/*
	 * This relies on the fact, that a transfer with NULL tx_buf shifts out
	 * zero bytes (=NOOP for MAX7301)
	 */
	ret = spi_read(spi, (u8 *)&word, sizeof(word));
	ret = spi_write_then_read(spi, &word, sizeof(word), &word,
				  sizeof(word));
	if (ret)
		return ret;
	return word & 0xff;
+3 −3
Original line number Diff line number Diff line
@@ -773,9 +773,6 @@ static int mvebu_pwm_probe(struct platform_device *pdev,
				     "marvell,armada-370-gpio"))
		return 0;

	if (IS_ERR(mvchip->clk))
		return PTR_ERR(mvchip->clk);

	/*
	 * There are only two sets of PWM configuration registers for
	 * all the GPIO lines on those SoCs which this driver reserves
@@ -786,6 +783,9 @@ static int mvebu_pwm_probe(struct platform_device *pdev,
	if (!res)
		return 0;

	if (IS_ERR(mvchip->clk))
		return PTR_ERR(mvchip->clk);

	/*
	 * Use set A for lines of GPIO chip with id 0, B for GPIO chip
	 * with id 1. Don't allow further GPIO chips to be used for PWM.
+5 −59
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@
#define OMAP4_GPIO_DEBOUNCINGTIME_MASK 0xFF

#define OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER	BIT(2)
#define OMAP_GPIO_QUIRK_DEFERRED_WKUP_EN	BIT(1)

struct gpio_regs {
	u32 irqenable1;
@@ -379,19 +378,10 @@ static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio,
			readl_relaxed(bank->base + bank->regs->fallingdetect);

	if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
		/* Defer wkup_en register update until we idle? */
		if (bank->quirks & OMAP_GPIO_QUIRK_DEFERRED_WKUP_EN) {
			if (trigger)
				bank->context.wake_en |= gpio_bit;
			else
				bank->context.wake_en &= ~gpio_bit;
		} else {
			omap_gpio_rmw(base, bank->regs->wkup_en, gpio_bit,
				      trigger != 0);
		omap_gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0);
		bank->context.wake_en =
			readl_relaxed(bank->base + bank->regs->wkup_en);
	}
	}

	/* This part needs to be executed always for OMAP{34xx, 44xx} */
	if (!bank->regs->irqctrl) {
@@ -942,44 +932,6 @@ omap2_gpio_disable_level_quirk(struct gpio_bank *bank)
		       bank->base + bank->regs->risingdetect);
}

/*
 * On omap4 and later SoC variants a level interrupt with wkup_en
 * enabled blocks the GPIO functional clock from idling until the GPIO
 * instance has been reset. To avoid that, we must set wkup_en only for
 * idle for level interrupts, and clear level registers for the duration
 * of idle. The level interrupts will be still there on wakeup by their
 * nature.
 */
static void __maybe_unused
omap4_gpio_enable_level_quirk(struct gpio_bank *bank)
{
	/* Update wake register for idle, edge bits might be already set */
	writel_relaxed(bank->context.wake_en,
		       bank->base + bank->regs->wkup_en);

	/* Clear level registers for idle */
	writel_relaxed(0, bank->base + bank->regs->leveldetect0);
	writel_relaxed(0, bank->base + bank->regs->leveldetect1);
}

static void __maybe_unused
omap4_gpio_disable_level_quirk(struct gpio_bank *bank)
{
	/* Restore level registers after idle */
	writel_relaxed(bank->context.leveldetect0,
		       bank->base + bank->regs->leveldetect0);
	writel_relaxed(bank->context.leveldetect1,
		       bank->base + bank->regs->leveldetect1);

	/* Clear saved wkup_en for level, it will be set for next idle again */
	bank->context.wake_en &= ~(bank->context.leveldetect0 |
				   bank->context.leveldetect1);

	/* Update wake with only edge configuration */
	writel_relaxed(bank->context.wake_en,
		       bank->base + bank->regs->wkup_en);
}

/*---------------------------------------------------------------------*/

static int omap_mpuio_suspend_noirq(struct device *dev)
@@ -1412,12 +1364,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
				omap_set_gpio_dataout_mask_multiple;
	}

	if (bank->quirks & OMAP_GPIO_QUIRK_DEFERRED_WKUP_EN) {
		bank->funcs.idle_enable_level_quirk =
			omap4_gpio_enable_level_quirk;
		bank->funcs.idle_disable_level_quirk =
			omap4_gpio_disable_level_quirk;
	} else if (bank->quirks & OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER) {
	if (bank->quirks & OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER) {
		bank->funcs.idle_enable_level_quirk =
			omap2_gpio_enable_level_quirk;
		bank->funcs.idle_disable_level_quirk =
@@ -1806,8 +1753,7 @@ static const struct omap_gpio_platform_data omap4_pdata = {
	.regs = &omap4_gpio_regs,
	.bank_width = 32,
	.dbck_flag = true,
	.quirks = OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER |
		  OMAP_GPIO_QUIRK_DEFERRED_WKUP_EN,
	.quirks = OMAP_GPIO_QUIRK_IDLE_REMOVE_TRIGGER,
};

static const struct of_device_id omap_gpio_match[] = {
+84 −60
Original line number Diff line number Diff line
@@ -19,11 +19,28 @@

#include "gpiolib.h"

/**
 * struct acpi_gpio_event - ACPI GPIO event handler data
 *
 * @node:	  list-entry of the events list of the struct acpi_gpio_chip
 * @handle:	  handle of ACPI method to execute when the IRQ triggers
 * @handler:	  irq_handler to pass to request_irq when requesting the IRQ
 * @pin:	  GPIO pin number on the gpio_chip
 * @irq:	  Linux IRQ number for the event, for request_ / free_irq
 * @irqflags:     flags to pass to request_irq when requesting the IRQ
 * @irq_is_wake:  If the ACPI flags indicate the IRQ is a wakeup source
 * @is_requested: True if request_irq has been done
 * @desc:	  gpio_desc for the GPIO pin for this event
 */
struct acpi_gpio_event {
	struct list_head node;
	acpi_handle handle;
	irq_handler_t handler;
	unsigned int pin;
	unsigned int irq;
	unsigned long irqflags;
	bool irq_is_wake;
	bool irq_requested;
	struct gpio_desc *desc;
};

@@ -49,10 +66,10 @@ struct acpi_gpio_chip {

/*
 * For gpiochips which call acpi_gpiochip_request_interrupts() before late_init
 * (so builtin drivers) we register the ACPI GpioInt event handlers from a
 * (so builtin drivers) we register the ACPI GpioInt IRQ handlers from a
 * late_initcall_sync handler, so that other builtin drivers can register their
 * OpRegions before the event handlers can run.  This list contains gpiochips
 * for which the acpi_gpiochip_request_interrupts() has been deferred.
 * for which the acpi_gpiochip_request_irqs() call has been deferred.
 */
static DEFINE_MUTEX(acpi_gpio_deferred_req_irqs_lock);
static LIST_HEAD(acpi_gpio_deferred_req_irqs_list);
@@ -133,7 +150,41 @@ bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
}
EXPORT_SYMBOL_GPL(acpi_gpio_get_irq_resource);

static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
static void acpi_gpiochip_request_irq(struct acpi_gpio_chip *acpi_gpio,
				      struct acpi_gpio_event *event)
{
	int ret, value;

	ret = request_threaded_irq(event->irq, NULL, event->handler,
				   event->irqflags, "ACPI:Event", event);
	if (ret) {
		dev_err(acpi_gpio->chip->parent,
			"Failed to setup interrupt handler for %d\n",
			event->irq);
		return;
	}

	if (event->irq_is_wake)
		enable_irq_wake(event->irq);

	event->irq_requested = true;

	/* Make sure we trigger the initial state of edge-triggered IRQs */
	value = gpiod_get_raw_value_cansleep(event->desc);
	if (((event->irqflags & IRQF_TRIGGER_RISING) && value == 1) ||
	    ((event->irqflags & IRQF_TRIGGER_FALLING) && value == 0))
		event->handler(event->irq, event);
}

static void acpi_gpiochip_request_irqs(struct acpi_gpio_chip *acpi_gpio)
{
	struct acpi_gpio_event *event;

	list_for_each_entry(event, &acpi_gpio->events, node)
		acpi_gpiochip_request_irq(acpi_gpio, event);
}

static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares,
					     void *context)
{
	struct acpi_gpio_chip *acpi_gpio = context;
@@ -143,8 +194,7 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
	struct acpi_gpio_event *event;
	irq_handler_t handler = NULL;
	struct gpio_desc *desc;
	unsigned long irqflags;
	int ret, pin, irq, value;
	int ret, pin, irq;

	if (!acpi_gpio_get_irq_resource(ares, &agpio))
		return AE_OK;
@@ -175,8 +225,6 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,

	gpiod_direction_input(desc);

	value = gpiod_get_value_cansleep(desc);

	ret = gpiochip_lock_as_irq(chip, pin);
	if (ret) {
		dev_err(chip->parent, "Failed to lock GPIO as interrupt\n");
@@ -189,64 +237,42 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
		goto fail_unlock_irq;
	}

	irqflags = IRQF_ONESHOT;
	event = kzalloc(sizeof(*event), GFP_KERNEL);
	if (!event)
		goto fail_unlock_irq;

	event->irqflags = IRQF_ONESHOT;
	if (agpio->triggering == ACPI_LEVEL_SENSITIVE) {
		if (agpio->polarity == ACPI_ACTIVE_HIGH)
			irqflags |= IRQF_TRIGGER_HIGH;
			event->irqflags |= IRQF_TRIGGER_HIGH;
		else
			irqflags |= IRQF_TRIGGER_LOW;
			event->irqflags |= IRQF_TRIGGER_LOW;
	} else {
		switch (agpio->polarity) {
		case ACPI_ACTIVE_HIGH:
			irqflags |= IRQF_TRIGGER_RISING;
			event->irqflags |= IRQF_TRIGGER_RISING;
			break;
		case ACPI_ACTIVE_LOW:
			irqflags |= IRQF_TRIGGER_FALLING;
			event->irqflags |= IRQF_TRIGGER_FALLING;
			break;
		default:
			irqflags |= IRQF_TRIGGER_RISING |
			event->irqflags |= IRQF_TRIGGER_RISING |
					   IRQF_TRIGGER_FALLING;
			break;
		}
	}

	event = kzalloc(sizeof(*event), GFP_KERNEL);
	if (!event)
		goto fail_unlock_irq;

	event->handle = evt_handle;
	event->handler = handler;
	event->irq = irq;
	event->irq_is_wake = agpio->wake_capable == ACPI_WAKE_CAPABLE;
	event->pin = pin;
	event->desc = desc;

	ret = request_threaded_irq(event->irq, NULL, handler, irqflags,
				   "ACPI:Event", event);
	if (ret) {
		dev_err(chip->parent,
			"Failed to setup interrupt handler for %d\n",
			event->irq);
		goto fail_free_event;
	}

	if (agpio->wake_capable == ACPI_WAKE_CAPABLE)
		enable_irq_wake(irq);

	list_add_tail(&event->node, &acpi_gpio->events);

	/*
	 * Make sure we trigger the initial state of the IRQ when using RISING
	 * or FALLING.  Note we run the handlers on late_init, the AML code
	 * may refer to OperationRegions from other (builtin) drivers which
	 * may be probed after us.
	 */
	if (((irqflags & IRQF_TRIGGER_RISING) && value == 1) ||
	    ((irqflags & IRQF_TRIGGER_FALLING) && value == 0))
		handler(event->irq, event);

	return AE_OK;

fail_free_event:
	kfree(event);
fail_unlock_irq:
	gpiochip_unlock_as_irq(chip, pin);
fail_free_desc:
@@ -283,6 +309,9 @@ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
	if (ACPI_FAILURE(status))
		return;

	acpi_walk_resources(handle, "_AEI",
			    acpi_gpiochip_alloc_event, acpi_gpio);

	mutex_lock(&acpi_gpio_deferred_req_irqs_lock);
	defer = !acpi_gpio_deferred_req_irqs_done;
	if (defer)
@@ -293,8 +322,7 @@ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
	if (defer)
		return;

	acpi_walk_resources(handle, "_AEI",
			    acpi_gpiochip_request_interrupt, acpi_gpio);
	acpi_gpiochip_request_irqs(acpi_gpio);
}
EXPORT_SYMBOL_GPL(acpi_gpiochip_request_interrupts);

@@ -331,10 +359,13 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip)
	list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) {
		struct gpio_desc *desc;

		if (irqd_is_wakeup_set(irq_get_irq_data(event->irq)))
		if (event->irq_requested) {
			if (event->irq_is_wake)
				disable_irq_wake(event->irq);

			free_irq(event->irq, event);
		}

		desc = event->desc;
		if (WARN_ON(IS_ERR(desc)))
			continue;
@@ -1200,23 +1231,16 @@ bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id)
	return con_id == NULL;
}

/* Run deferred acpi_gpiochip_request_interrupts() */
static int acpi_gpio_handle_deferred_request_interrupts(void)
/* Run deferred acpi_gpiochip_request_irqs() */
static int acpi_gpio_handle_deferred_request_irqs(void)
{
	struct acpi_gpio_chip *acpi_gpio, *tmp;

	mutex_lock(&acpi_gpio_deferred_req_irqs_lock);
	list_for_each_entry_safe(acpi_gpio, tmp,
				 &acpi_gpio_deferred_req_irqs_list,
				 deferred_req_irqs_list_entry) {
		acpi_handle handle;

		handle = ACPI_HANDLE(acpi_gpio->chip->parent);
		acpi_walk_resources(handle, "_AEI",
				    acpi_gpiochip_request_interrupt, acpi_gpio);

		list_del_init(&acpi_gpio->deferred_req_irqs_list_entry);
	}
				 deferred_req_irqs_list_entry)
		acpi_gpiochip_request_irqs(acpi_gpio);

	acpi_gpio_deferred_req_irqs_done = true;
	mutex_unlock(&acpi_gpio_deferred_req_irqs_lock);
@@ -1224,4 +1248,4 @@ static int acpi_gpio_handle_deferred_request_interrupts(void)
	return 0;
}
/* We must use _sync so that this runs after the first deferred_probe run */
late_initcall_sync(acpi_gpio_handle_deferred_request_interrupts);
late_initcall_sync(acpi_gpio_handle_deferred_request_irqs);