GPIO fixes for v5.3:
- 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. -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEElDRnuGcz/wPCXQWMQRCzN7AZXXMFAl15/G8ACgkQQRCzN7AZ XXOpKA/8D1yRVDehYXgL5vH9AweXtUN82t2ZKeN5Mu+XiTJ2DMI1tS3lNrgwlnew 3nJ/o8hgR7O2ZTmNXcQ/tyw6+svCi9bGQjYnhmqVx5u2dyhxjFg5gLJJNT+Mrzw/ 7AnD05oBV4yGtRyscgfr9ODJR8Qy2a9el/5SSm1rAOgwRgtKviKFnv3crasWrS/m TavpO/BtQOH8gUByR8sIaOFSMzKYc66Km9CQLdmcpfCOksz3E1lx4MlPghA7Fs7G p2M3883mYQrK6Ya2ZUEOwbPG48JPmGHK0rGwTH2GASd0F1tfLxaxmBMdDOQ4KAjx V3sWiCyR5RscehB/TWRcDl63o2HyZv6DYggYwDeNPx3Lck3WO+BLhv+RGjhXC46p QWU+c0WoZeAKfd3S63N/68mVh/7EpK9ef9Nq/vv2IKxI0THn3ZI6xg70fsgdl7wW s/KMOpqmztxmaQIlthzMmQSRnKO9sbv5Zy58SWOA992BNbgbRVjkHjTkdcu6UXJ7 aURX/k/3/6alMxTBLITWdax+ihjuwpdhX0VVf5qPGh1/WdMq5DAI79bUQAdvrPW6 Q0YFhQqZNTBzCOWXSXEtUJiSI7a0Wrnf0bKIFXTu7qQ7Fw+ohqliY8qOs+m1hm8f 6nYrS5JQKoGHbTVxL0/0m83f8OyQGnZiy7FEdBGYNKcSGec5rao= =QEAT -----END PGP SIGNATURE----- Merge tag 'gpio-v5.3-6' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio 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()alistair/sunxi64-5.4-dsi
commit
9c09f62348
|
@ -309,6 +309,7 @@ static const struct file_operations gpio_mockup_debugfs_ops = {
|
||||||
.read = gpio_mockup_debugfs_read,
|
.read = gpio_mockup_debugfs_read,
|
||||||
.write = gpio_mockup_debugfs_write,
|
.write = gpio_mockup_debugfs_write,
|
||||||
.llseek = no_llseek,
|
.llseek = no_llseek,
|
||||||
|
.release = single_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void gpio_mockup_debugfs_setup(struct device *dev,
|
static void gpio_mockup_debugfs_setup(struct device *dev,
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
* Mika Westerberg <mika.westerberg@linux.intel.com>
|
* Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/dmi.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/gpio/consumer.h>
|
#include <linux/gpio/consumer.h>
|
||||||
#include <linux/gpio/driver.h>
|
#include <linux/gpio/driver.h>
|
||||||
|
@ -19,6 +20,11 @@
|
||||||
|
|
||||||
#include "gpiolib.h"
|
#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
|
* struct acpi_gpio_event - ACPI GPIO event handler data
|
||||||
*
|
*
|
||||||
|
@ -170,10 +176,13 @@ static void acpi_gpiochip_request_irq(struct acpi_gpio_chip *acpi_gpio,
|
||||||
event->irq_requested = true;
|
event->irq_requested = true;
|
||||||
|
|
||||||
/* Make sure we trigger the initial state of edge-triggered IRQs */
|
/* Make sure we trigger the initial state of edge-triggered IRQs */
|
||||||
value = gpiod_get_raw_value_cansleep(event->desc);
|
if (run_edge_events_on_boot &&
|
||||||
if (((event->irqflags & IRQF_TRIGGER_RISING) && value == 1) ||
|
(event->irqflags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))) {
|
||||||
((event->irqflags & IRQF_TRIGGER_FALLING) && value == 0))
|
value = gpiod_get_raw_value_cansleep(event->desc);
|
||||||
event->handler(event->irq, event);
|
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)
|
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 */
|
/* We must use _sync so that this runs after the first deferred_probe run */
|
||||||
late_initcall_sync(acpi_gpio_handle_deferred_request_irqs);
|
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);
|
||||||
|
|
|
@ -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,
|
desc = of_get_named_gpiod_flags(dev->of_node, prop_name, idx,
|
||||||
&of_flags);
|
&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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Special handling for SPI GPIOs if used */
|
if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT) {
|
||||||
if (IS_ERR(desc))
|
/* Special handling for SPI GPIOs if used */
|
||||||
desc = of_find_spi_gpio(dev, con_id, &of_flags);
|
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 */
|
/* This quirk looks up flags and all */
|
||||||
desc = of_find_spi_cs_gpio(dev, con_id, idx, flags);
|
desc = of_find_spi_cs_gpio(dev, con_id, idx, flags);
|
||||||
if (!IS_ERR(desc))
|
if (!IS_ERR(desc))
|
||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Special handling for regulator GPIOs if used */
|
if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT) {
|
||||||
if (IS_ERR(desc) && PTR_ERR(desc) != -EPROBE_DEFER)
|
/* Special handling for regulator GPIOs if used */
|
||||||
desc = of_find_regulator_gpio(dev, con_id, &of_flags);
|
desc = of_find_regulator_gpio(dev, con_id, &of_flags);
|
||||||
|
}
|
||||||
|
|
||||||
if (IS_ERR(desc))
|
if (IS_ERR(desc))
|
||||||
return desc;
|
return desc;
|
||||||
|
|
|
@ -535,6 +535,14 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
|
||||||
if (lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS)
|
if (lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS)
|
||||||
return -EINVAL;
|
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
|
* Do not allow OPEN_SOURCE & OPEN_DRAIN flags in a single request. If
|
||||||
* the hardware actually supports enabling both at the same time the
|
* 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 */
|
/* 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;
|
ret = -EINVAL;
|
||||||
goto out_free_label;
|
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)
|
if (lflags & GPIOHANDLE_REQUEST_ACTIVE_LOW)
|
||||||
set_bit(FLAG_ACTIVE_LOW, &desc->flags);
|
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);
|
ret = gpiod_direction_input(desc);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
Loading…
Reference in New Issue