GPIO fixes for the v5.5 kernel cycle:
- Select GPIOLIB_IRQCHIP on the max77620 GPIO expander - Fix context restore in the Zynq driver - Create a new ACPI quirk handler for disabling wakeups on problematic hardware. - Fix a coding style issue on the mockup device. -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEElDRnuGcz/wPCXQWMQRCzN7AZXXMFAl4XoYIACgkQQRCzN7AZ XXM7IA//WDmeJw/8yfr5SmbTE6xCLAVR86KEksepNiQkTzgI1FivZ6RNIxxTdHKe tcFc3HPyGO6T6Fs7sdUpdQI2RY7JAF4Egr6HItzv/SkYrdsvaQdVr6pRVb0az0Ad EymV+Kq2skLsAg4D5nBDYDjUAlLdE/61f/OgaKfJvLAk9hE4lA0Lg19An1BEzfeZ oSn26hCfmffRfTW9KCD3xie8j2zzpOR6Nw3LrDmqNF2gk9NiZkU3qIdcqkHUm0TL CXRVZjz36pXAwnLn7DUrgEf283lJ4awOM0zZS+YfVJ7v0rcPdvzgwPBNzu85Uvxx VrgR1UdEZFx0tW020HUS8dRdBhw6ttopwB6eqSU2r9KX47dhf7w7wV8KaJkG/cUN bp9R9TCGH5mFCQMR8owOFqwvjw9uNmcZ4oVpgIXHJ2cMENBRp7WCrV/4y/o8m4sU GTAJx/AYoUxro68trPWMLcQkA+qV7qESScxG0DsRZ5kflIbV1mS8n5K+yc0KwgXf +a39wSQxTTXT1bW+qy8jSGFr8+hbvQ/plTRnNa+aIlx89yYfY4WrMgcp0GwUGSc7 GkEw58w7wrqgTRy2oF3IFnagX3x8rmUmeZU7Yjkhl4xjbX5Le/6awDX0HlRnVSg9 tN8dVbQkzuB8KU6ewQjn2cuFhEN+Xoc5NPO9fQyli2MdlKUcHDI= =IbMi -----END PGP SIGNATURE----- Merge tag 'gpio-v5.5-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio Pull GPIO fixes from Linus Walleij: "Here is a host of GPIO fixes for the v5.5 series. The ACPI fix is especially important, see summary below and in the commit for details: - Select GPIOLIB_IRQCHIP on the max77620 GPIO expander - Fix context restore in the Zynq driver - Create a new ACPI quirk handler for disabling wakeups on problematic hardware. - Fix a coding style issue on the mockup device" * tag 'gpio-v5.5-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: gpiolib: acpi: Add honor_wakeup module-option + quirk mechanism gpiolib: acpi: Turn dmi_system_id table into a generic quirk table gpio: zynq: Fix for bug in zynq_gpio_restore_context API gpio: max77620: Add missing dependency on GPIOLIB_IRQCHIP gpio: mockup: fix coding style
This commit is contained in:
commit
4a3033ef6e
|
@ -1148,6 +1148,7 @@ config GPIO_MADERA
|
||||||
config GPIO_MAX77620
|
config GPIO_MAX77620
|
||||||
tristate "GPIO support for PMIC MAX77620 and MAX20024"
|
tristate "GPIO support for PMIC MAX77620 and MAX20024"
|
||||||
depends on MFD_MAX77620
|
depends on MFD_MAX77620
|
||||||
|
select GPIOLIB_IRQCHIP
|
||||||
help
|
help
|
||||||
GPIO driver for MAX77620 and MAX20024 PMIC from Maxim Semiconductor.
|
GPIO driver for MAX77620 and MAX20024 PMIC from Maxim Semiconductor.
|
||||||
MAX77620 PMIC has 8 pins that can be configured as GPIOs. The
|
MAX77620 PMIC has 8 pins that can be configured as GPIOs. The
|
||||||
|
|
|
@ -156,7 +156,7 @@ static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip,
|
||||||
mutex_lock(&chip->lock);
|
mutex_lock(&chip->lock);
|
||||||
|
|
||||||
if (test_bit(FLAG_REQUESTED, &desc->flags) &&
|
if (test_bit(FLAG_REQUESTED, &desc->flags) &&
|
||||||
!test_bit(FLAG_IS_OUT, &desc->flags)) {
|
!test_bit(FLAG_IS_OUT, &desc->flags)) {
|
||||||
curr = __gpio_mockup_get(chip, offset);
|
curr = __gpio_mockup_get(chip, offset);
|
||||||
if (curr == value)
|
if (curr == value)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -165,7 +165,7 @@ static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip,
|
||||||
irq_type = irq_get_trigger_type(irq);
|
irq_type = irq_get_trigger_type(irq);
|
||||||
|
|
||||||
if ((value == 1 && (irq_type & IRQ_TYPE_EDGE_RISING)) ||
|
if ((value == 1 && (irq_type & IRQ_TYPE_EDGE_RISING)) ||
|
||||||
(value == 0 && (irq_type & IRQ_TYPE_EDGE_FALLING)))
|
(value == 0 && (irq_type & IRQ_TYPE_EDGE_FALLING)))
|
||||||
irq_sim_fire(sim, offset);
|
irq_sim_fire(sim, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -684,6 +684,8 @@ static void zynq_gpio_restore_context(struct zynq_gpio *gpio)
|
||||||
unsigned int bank_num;
|
unsigned int bank_num;
|
||||||
|
|
||||||
for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++) {
|
for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++) {
|
||||||
|
writel_relaxed(ZYNQ_GPIO_IXR_DISABLE_ALL, gpio->base_addr +
|
||||||
|
ZYNQ_GPIO_INTDIS_OFFSET(bank_num));
|
||||||
writel_relaxed(gpio->context.datalsw[bank_num],
|
writel_relaxed(gpio->context.datalsw[bank_num],
|
||||||
gpio->base_addr +
|
gpio->base_addr +
|
||||||
ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num));
|
ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num));
|
||||||
|
@ -693,9 +695,6 @@ static void zynq_gpio_restore_context(struct zynq_gpio *gpio)
|
||||||
writel_relaxed(gpio->context.dirm[bank_num],
|
writel_relaxed(gpio->context.dirm[bank_num],
|
||||||
gpio->base_addr +
|
gpio->base_addr +
|
||||||
ZYNQ_GPIO_DIRM_OFFSET(bank_num));
|
ZYNQ_GPIO_DIRM_OFFSET(bank_num));
|
||||||
writel_relaxed(gpio->context.int_en[bank_num],
|
|
||||||
gpio->base_addr +
|
|
||||||
ZYNQ_GPIO_INTEN_OFFSET(bank_num));
|
|
||||||
writel_relaxed(gpio->context.int_type[bank_num],
|
writel_relaxed(gpio->context.int_type[bank_num],
|
||||||
gpio->base_addr +
|
gpio->base_addr +
|
||||||
ZYNQ_GPIO_INTTYPE_OFFSET(bank_num));
|
ZYNQ_GPIO_INTTYPE_OFFSET(bank_num));
|
||||||
|
@ -705,6 +704,9 @@ static void zynq_gpio_restore_context(struct zynq_gpio *gpio)
|
||||||
writel_relaxed(gpio->context.int_any[bank_num],
|
writel_relaxed(gpio->context.int_any[bank_num],
|
||||||
gpio->base_addr +
|
gpio->base_addr +
|
||||||
ZYNQ_GPIO_INTANY_OFFSET(bank_num));
|
ZYNQ_GPIO_INTANY_OFFSET(bank_num));
|
||||||
|
writel_relaxed(~(gpio->context.int_en[bank_num]),
|
||||||
|
gpio->base_addr +
|
||||||
|
ZYNQ_GPIO_INTEN_OFFSET(bank_num));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,11 +21,19 @@
|
||||||
#include "gpiolib.h"
|
#include "gpiolib.h"
|
||||||
#include "gpiolib-acpi.h"
|
#include "gpiolib-acpi.h"
|
||||||
|
|
||||||
|
#define QUIRK_NO_EDGE_EVENTS_ON_BOOT 0x01l
|
||||||
|
#define QUIRK_NO_WAKEUP 0x02l
|
||||||
|
|
||||||
static int run_edge_events_on_boot = -1;
|
static int run_edge_events_on_boot = -1;
|
||||||
module_param(run_edge_events_on_boot, int, 0444);
|
module_param(run_edge_events_on_boot, int, 0444);
|
||||||
MODULE_PARM_DESC(run_edge_events_on_boot,
|
MODULE_PARM_DESC(run_edge_events_on_boot,
|
||||||
"Run edge _AEI event-handlers at boot: 0=no, 1=yes, -1=auto");
|
"Run edge _AEI event-handlers at boot: 0=no, 1=yes, -1=auto");
|
||||||
|
|
||||||
|
static int honor_wakeup = -1;
|
||||||
|
module_param(honor_wakeup, int, 0444);
|
||||||
|
MODULE_PARM_DESC(honor_wakeup,
|
||||||
|
"Honor the ACPI wake-capable flag: 0=no, 1=yes, -1=auto");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct acpi_gpio_event - ACPI GPIO event handler data
|
* struct acpi_gpio_event - ACPI GPIO event handler data
|
||||||
*
|
*
|
||||||
|
@ -281,7 +289,7 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares,
|
||||||
event->handle = evt_handle;
|
event->handle = evt_handle;
|
||||||
event->handler = handler;
|
event->handler = handler;
|
||||||
event->irq = irq;
|
event->irq = irq;
|
||||||
event->irq_is_wake = agpio->wake_capable == ACPI_WAKE_CAPABLE;
|
event->irq_is_wake = honor_wakeup && agpio->wake_capable == ACPI_WAKE_CAPABLE;
|
||||||
event->pin = pin;
|
event->pin = pin;
|
||||||
event->desc = desc;
|
event->desc = desc;
|
||||||
|
|
||||||
|
@ -1309,7 +1317,7 @@ 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[] = {
|
static const struct dmi_system_id gpiolib_acpi_quirks[] = {
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The Minix Neo Z83-4 has a micro-USB-B id-pin handler for
|
* The Minix Neo Z83-4 has a micro-USB-B id-pin handler for
|
||||||
|
@ -1319,7 +1327,8 @@ static const struct dmi_system_id run_edge_events_on_boot_blacklist[] = {
|
||||||
.matches = {
|
.matches = {
|
||||||
DMI_MATCH(DMI_SYS_VENDOR, "MINIX"),
|
DMI_MATCH(DMI_SYS_VENDOR, "MINIX"),
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"),
|
||||||
}
|
},
|
||||||
|
.driver_data = (void *)QUIRK_NO_EDGE_EVENTS_ON_BOOT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -1331,20 +1340,52 @@ static const struct dmi_system_id run_edge_events_on_boot_blacklist[] = {
|
||||||
.matches = {
|
.matches = {
|
||||||
DMI_MATCH(DMI_SYS_VENDOR, "Wortmann_AG"),
|
DMI_MATCH(DMI_SYS_VENDOR, "Wortmann_AG"),
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "TERRA_PAD_1061"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "TERRA_PAD_1061"),
|
||||||
}
|
},
|
||||||
|
.driver_data = (void *)QUIRK_NO_EDGE_EVENTS_ON_BOOT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Various HP X2 10 Cherry Trail models use an external
|
||||||
|
* embedded-controller connected via I2C + an ACPI GPIO
|
||||||
|
* event handler. The embedded controller generates various
|
||||||
|
* spurious wakeup events when suspended. So disable wakeup
|
||||||
|
* for its handler (it uses the only ACPI GPIO event handler).
|
||||||
|
* This breaks wakeup when opening the lid, the user needs
|
||||||
|
* to press the power-button to wakeup the system. The
|
||||||
|
* alternative is suspend simply not working, which is worse.
|
||||||
|
*/
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"),
|
||||||
|
},
|
||||||
|
.driver_data = (void *)QUIRK_NO_WAKEUP,
|
||||||
},
|
},
|
||||||
{} /* Terminating entry */
|
{} /* Terminating entry */
|
||||||
};
|
};
|
||||||
|
|
||||||
static int acpi_gpio_setup_params(void)
|
static int acpi_gpio_setup_params(void)
|
||||||
{
|
{
|
||||||
|
const struct dmi_system_id *id;
|
||||||
|
long quirks = 0;
|
||||||
|
|
||||||
|
id = dmi_first_match(gpiolib_acpi_quirks);
|
||||||
|
if (id)
|
||||||
|
quirks = (long)id->driver_data;
|
||||||
|
|
||||||
if (run_edge_events_on_boot < 0) {
|
if (run_edge_events_on_boot < 0) {
|
||||||
if (dmi_check_system(run_edge_events_on_boot_blacklist))
|
if (quirks & QUIRK_NO_EDGE_EVENTS_ON_BOOT)
|
||||||
run_edge_events_on_boot = 0;
|
run_edge_events_on_boot = 0;
|
||||||
else
|
else
|
||||||
run_edge_events_on_boot = 1;
|
run_edge_events_on_boot = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (honor_wakeup < 0) {
|
||||||
|
if (quirks & QUIRK_NO_WAKEUP)
|
||||||
|
honor_wakeup = 0;
|
||||||
|
else
|
||||||
|
honor_wakeup = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue