Commit 9c09f623 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull GPIO fixes from Linus Walleij:
 "I don't really like to send so many fixes at the very last minute, but
  the bug-sport activity is unpredictable.

  Four fixes, three are -stable material that will go everywhere, one is
  for the current cycle:

   - An ACPI DSDT error fixup of the type we always see and Hans
     invariably gets to fix.

   - A OF quirk fix for the current release (v5.3)

   - Some consistency checks on the userspace ABI.

   - A memory leak"

* tag 'gpio-v5.3-6' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio:
  gpiolib: acpi: Add gpiolib_acpi_run_edge_events_on_boot option and blacklist
  gpiolib: of: fix fallback quirks handling
  gpio: fix line flag validation in lineevent_create
  gpio: fix line flag validation in linehandle_create
  gpio: mockup: add missing single_release()
parents 3120b9a6 61f7f7c8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -309,6 +309,7 @@ static const struct file_operations gpio_mockup_debugfs_ops = {
	.read = gpio_mockup_debugfs_read,
	.write = gpio_mockup_debugfs_write,
	.llseek = no_llseek,
	.release = single_release,
};

static void gpio_mockup_debugfs_setup(struct device *dev,
+38 −4
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
 *          Mika Westerberg <mika.westerberg@linux.intel.com>
 */

#include <linux/dmi.h>
#include <linux/errno.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h>
@@ -19,6 +20,11 @@

#include "gpiolib.h"

static int run_edge_events_on_boot = -1;
module_param(run_edge_events_on_boot, int, 0444);
MODULE_PARM_DESC(run_edge_events_on_boot,
		 "Run edge _AEI event-handlers at boot: 0=no, 1=yes, -1=auto");

/**
 * struct acpi_gpio_event - ACPI GPIO event handler data
 *
@@ -170,11 +176,14 @@ static void acpi_gpiochip_request_irq(struct acpi_gpio_chip *acpi_gpio,
	event->irq_requested = true;

	/* Make sure we trigger the initial state of edge-triggered IRQs */
	if (run_edge_events_on_boot &&
	    (event->irqflags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))) {
		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)
{
@@ -1283,3 +1292,28 @@ static int acpi_gpio_handle_deferred_request_irqs(void)
}
/* We must use _sync so that this runs after the first deferred_probe run */
late_initcall_sync(acpi_gpio_handle_deferred_request_irqs);

static const struct dmi_system_id run_edge_events_on_boot_blacklist[] = {
	{
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "MINIX"),
			DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"),
		}
	},
	{} /* Terminating entry */
};

static int acpi_gpio_setup_params(void)
{
	if (run_edge_events_on_boot < 0) {
		if (dmi_check_system(run_edge_events_on_boot_blacklist))
			run_edge_events_on_boot = 0;
		else
			run_edge_events_on_boot = 1;
	}

	return 0;
}

/* Directly after dmi_setup() which runs as core_initcall() */
postcore_initcall(acpi_gpio_setup_params);
+9 −18
Original line number Diff line number Diff line
@@ -343,36 +343,27 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,

		desc = of_get_named_gpiod_flags(dev->of_node, prop_name, idx,
						&of_flags);
		/*
		 * -EPROBE_DEFER in our case means that we found a
		 * valid GPIO property, but no controller has been
		 * registered so far.
		 *
		 * This means we don't need to look any further for
		 * alternate name conventions, and we should really
		 * preserve the return code for our user to be able to
		 * retry probing later.
		 */
		if (IS_ERR(desc) && PTR_ERR(desc) == -EPROBE_DEFER)
			return desc;

		if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT))
		if (!IS_ERR(desc) || PTR_ERR(desc) != -ENOENT)
			break;
	}

	if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT) {
		/* Special handling for SPI GPIOs if used */
	if (IS_ERR(desc))
		desc = of_find_spi_gpio(dev, con_id, &of_flags);
	if (IS_ERR(desc) && PTR_ERR(desc) != -EPROBE_DEFER) {
	}

	if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT) {
		/* This quirk looks up flags and all */
		desc = of_find_spi_cs_gpio(dev, con_id, idx, flags);
		if (!IS_ERR(desc))
			return desc;
	}

	if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT) {
		/* Special handling for regulator GPIOs if used */
	if (IS_ERR(desc) && PTR_ERR(desc) != -EPROBE_DEFER)
		desc = of_find_regulator_gpio(dev, con_id, &of_flags);
	}

	if (IS_ERR(desc))
		return desc;
+11 −5
Original line number Diff line number Diff line
@@ -535,6 +535,14 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
	if (lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS)
		return -EINVAL;

	/*
	 * Do not allow both INPUT & OUTPUT flags to be set as they are
	 * contradictory.
	 */
	if ((lflags & GPIOHANDLE_REQUEST_INPUT) &&
	    (lflags & GPIOHANDLE_REQUEST_OUTPUT))
		return -EINVAL;

	/*
	 * Do not allow OPEN_SOURCE & OPEN_DRAIN flags in a single request. If
	 * the hardware actually supports enabling both at the same time the
@@ -926,7 +934,9 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
	}

	/* This is just wrong: we don't look for events on output lines */
	if (lflags & GPIOHANDLE_REQUEST_OUTPUT) {
	if ((lflags & GPIOHANDLE_REQUEST_OUTPUT) ||
	    (lflags & GPIOHANDLE_REQUEST_OPEN_DRAIN) ||
	    (lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE)) {
		ret = -EINVAL;
		goto out_free_label;
	}
@@ -940,10 +950,6 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)

	if (lflags & GPIOHANDLE_REQUEST_ACTIVE_LOW)
		set_bit(FLAG_ACTIVE_LOW, &desc->flags);
	if (lflags & GPIOHANDLE_REQUEST_OPEN_DRAIN)
		set_bit(FLAG_OPEN_DRAIN, &desc->flags);
	if (lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE)
		set_bit(FLAG_OPEN_SOURCE, &desc->flags);

	ret = gpiod_direction_input(desc);
	if (ret)